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构造函数?

book1928 回答:Python,为什么我们可以创建类创建中未定义的类变量?

class对象只是另一种类型的实例,通常是type(尽管您可以使用metaclass语句的class参数来更改它)。 / p>

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

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

__init__没什么特别的;它只是可以将新属性附加到对象的另一种方法。 的特别之处在于,当您通过调用类创建新的类实例时,__init__被自动称为 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的三参数形式使您可以通过dict来创建类属性,而该类在您首次创建类时就可以创建,但是您也可以始终在事实之后分配属性:

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

只是稍微动弹了一下,对type的调用可能就像是

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

尽管除非定义了自定义元类(通过对type进行子类化),否则您不必考虑type本身具有__new____init__方法的情况。

,

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

是的

我们为什么要创建一个在该类的原始定义中未定义的新类变量?

因为Python是一种动态语言。可以在运行时创建类-实际上,是在您交互式运行Python时在运行时创建的

那么我们可以在运行时创建新的类属性吗?

是的,除非元类(该类的类)禁止了它。

这如何不干扰创建类对象并将这些类变量作为类对象的实例变量的init构造函数?

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

>>> 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允许您随时向对象添加属性,但某些类(例如object)禁止添加属性。

使用类a的上一个MyClass对象,您可以执行以下操作:

a.z_var = 12

从那时起,z_var将是a的属性,但同一类的其他对象将没有它。

object仅禁止:

>>> o = object()
>>> o.x=1
Traceback (most recent call last):
  File "<pyshell#41>",in <module>
    o.x=1
AttributeError: 'object' object has no attribute 'x'
本文链接:https://www.f2er.com/2638566.html

大家都在问