python - Python,为什么我们可以创建在类创建中没有定义的类变量?
问题描述
假设我们有这个简单的 Python 代码
class MyClass(object):
class_var = 1
def __init__(self, i_var):
self.i_var = i_var
如果我有任何错误,请纠正我:
Class_Var 是一个类变量,对于 MyClass 对象的所有实例都是相同的。I_Var 是一个实例变量,只存在于 MyClass 对象的实例中
foo = MyClass(2)
bar = MyClass(3)
foo.class_var, foo.i_var
## 1, 2
bar.class_var, bar.i_var
## 1, 3
类变量也是类本身的属性。
MyClass.class_var ##
## 1
MyClass.I_var 应该出错,对吗?
这是否意味着类变量可以被视为类对象本身的实例变量(因为所有类都是对象)?
MyClass.new_attribute = 'foo'
print(hasattr(ObjectCreator, 'new_attribute'))
那应该返回true。和
print (MyClass.new_attribute)
应该返回 foo。
为什么我们可以创建一个未在该类的原始定义中定义的新类变量?
是
MyClass.new_attribute = 'foo'
与在原始定义中创建该类属性完全相同吗?
class MyClass(object):
class_var = 1
new_attribute = 'foo'
那么我们可以在运行时创建新的类属性吗?这如何不干扰创建类对象并将这些类变量作为类对象的实例变量的 init 构造函数?
解决方案
通常class
,对象只是另一种类型的实例type
(尽管您可以使用语句的metaclass
参数来更改它)。class
与大多数其他实例一样,您可以随时向对象添加任意实例属性class
。
类属性和实例属性是完全分开的;前者存储在class
对象上,后者存储在类的实例上。
没有什么特别的__init__
;它只是另一种方法,除其他外,可以将新属性附加到对象。特殊的是当你通过__init__
调用类创建类的新实例时会自动调用它。foo = MyClass(2)
相当于
foo = MyClass.__new__(MyClass, 2)
foo.__init__(2)
班级声明
class MyClass(object):
class_var = 1
def __init__(self, i_var):
self.i_var = i_var
大致相当于
def my_class_init(self, i_var):
self.i_var = i_var
MyClass = type('MyClass', (object,), {'class_var': 1, '__init__: my_class_init})
的 3 参数形式type
允许您dict
在第一次创建类时传递创建类属性的 a,但您也始终可以在事后分配属性:
MyClass = type('MyClass', (object,), {})
MyClass.class_var = 1
MyClass.__init__ = my_class_init
只是为了让你更震撼一点,调用 totype
可以被认为是
MyClass = type.__new__(type, 'MyClass', (object,), {...})
MyClass.__init__('MyClass', (object,), {...})
尽管除非您定义自定义元类(通过子类化type
),否则您永远不必考虑type
自己拥有__new__
和__init__
方法。
推荐阅读
- assembly - 为什么在更改单条指令时这段代码没有命中 Haswell 上的微操作缓存?
- scala - 处理具有高阶函数的 Scala 选项类型
- java - eclipse中的Kafka Producer不向主题发送消息
- javascript - thunk 和函数柯里化是一样的吗?
- oracle - 使用 pl\sql 根据计数和时间戳删除数据
- elasticsearch - Filebeat 无法将数据发送到 logstash,导致 elastic & kibana 中的数据为空
- python-3.x - 遮蔽层的效果
- node.js - 在另一个自定义 npm 包中安装自定义 npm 包
- html - 反应形式的输入/离子输入 - ChangeDetectionStrategy 的问题
- python - 抓取表只返回“表”而不是表的内容