Python,为什么我们可以创建 class 个在 class 创建时未定义的变量?

Python, how come we can create class variables that were not defined in class creation?

假设我们有这个简单的 Python 代码

class MyClass(object):
    class_var = 1

    def __init__(self, i_var):
        self.i_var = i_var

如果我有任何错误,请纠正我:

Class_Var 是一个 class 变量,它对于 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

Class 变量也是 class 本身的属性。

MyClass.class_var ##
## 1

MyClass.I_var应该会出错,对吗?

这是否意味着 class 变量可以被视为 class 对象本身的实例变量(因为所有 class 都是对象)?

MyClass.new_attribute = 'foo'
print(hasattr(ObjectCreator, 'new_attribute'))

那应该 return 正确。并且

print (MyClass.new_attribute)

应该return foo.

为什么我们可以创建一个新的 class 变量,而该 class 的原始定义中并未定义该变量?

MyClass.new_attribute = 'foo'

与在原始定义中创建 class 属性完全相同?

class MyClass(object):
    class_var = 1
    new_attribute = 'foo'

所以我们可以在运行时创建新的 class 属性?这如何不干扰创建 class 对象并将那些 class 变量作为 class 对象的实例变量的 init 构造函数?

A class 对象只是另一种类型的实例,通常是 type(尽管您可以使用 metaclass 参数将其更改为 class 语句) .

与大多数其他实例一样,您可以随时向 class 对象添加任意实例属性。

Class属性和实例属性是完全分开的;前者存储在 class 对象上,后者存储在 class.

的实例上

__init__没什么特别的;它只是另一种方法,除其他外,可以将新属性附加到对象。 的特别之处在于,当您通过调用class。 foo = MyClass(2) 等同于

foo = MyClass.__new__(MyClass, 2)
foo.__init__(2)

class声明

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})

type 的 3 参数形式允许您在首次创建 class 时传递创建 class 属性的 dict,但您始终可以分配属性事后也是:

MyClass = type('MyClass', (object,), {})
MyClass.class_var = 1
MyClass.__init__ = my_class_init

只是让你的想法更 一点,对 type 的调用可以被认为是

MyClass = type.__new__(type, 'MyClass', (object,), {...})
MyClass.__init__('MyClass', (object,), {...})

尽管除非你定义自定义元class(通过subclassing type),你永远不必考虑type本身有__new____init__ 方法。

Does that mean that class variables can be considered like instance variables of the class object itself (since all classes are objects) ?

是的。

How come we can create a new class variable that was not defined in the original definition for that class?

因为Python是动态语言。一个 class 可以在 运行 时间创建 - 事实上,它 在 运行 时间创建的,而你 运行 Python 交互。

So we can create new class attributes at runtime?

是的,除非 metaclass(class 的 class)禁止它。

How does that not interfere with the init constructor that creates the class object and has those class variables as instance variables of the class object?

唯一的规则是您不能使用尚未定义或已删除的内容:

>>> class MyClass(object):
    class_var = 1

    def __init__(self, i_var):
        self.i_var = i_var
        self.j_var = self.class_var + 1


>>> a = MyClass(2)
>>> del MyClass.class_var
>>> b = MyClass(3)
Traceback (most recent call last):
  File "<pyshell#39>", line 1, in <module>
    b = MyClass(3)
  File "<pyshell#36>", line 6, in __init__
    self.j_var = self.class_var + 1
AttributeError: 'MyClass' object has no attribute 'class_var'

这里没有魔法:任何东西都只能存在于它的定义点和它的破坏点之间。 Python 允许您随时为对象添加属性,除了某些 classes(例如 object)禁止它。

使用 class MyClass 的前一个 a 对象,你可以这样做:

a.z_var = 12

从那时起,z_var 将成为 a 的属性,但相同 class 的其他对象将没有它。

只是object禁止:

>>> o = object()
>>> o.x=1
Traceback (most recent call last):
  File "<pyshell#41>", line 1, in <module>
    o.x=1
AttributeError: 'object' object has no attribute 'x'