类的特定实例可以在python中创建自己的变量吗?

时间:2018-05-27 17:40:00

标签: python

特定实例是否可以在python中创建自己的变量,如果是,它是否可用于该类的其他实例?

例如:

class A():
    Var1 = 10

inst1 = A()

inst1.Var1 # will be 10

但是inst1可以使它自己的变量像Var2等,这些变量是否可用于其他类的实例,如inst2?

换句话说,是一个变量,它绑定到一个类的实例,可以被同一个类的另一个实例访问吗?

4 个答案:

答案 0 :(得分:1)

要动态地向类或实例添加属性,可以使用setattr

class MyClass(object):
    pass

my_instance = MyClass()


# add attribute to class
setattr(MyClass, 'new_attribute', 'added')

# Class now has attribute
print(MyClass.new_attribute == 'added')  # True

# Which is also available to instance
print(my_instance.new_attribute == 'added')  # True

# Add attribute to instance
setattr(my_instance, 'instance_only', 'yup')

# Instance now has attribute
print(my_instance.instance_only == 'yup')  # True

# Class does not have attribute
MyClass.instance_only # Raises AttributeError

# Add attribute to instances class
settatr(type(my_instance), 'instance_only', 'not anymore')

# Now the attribute is available to the class as well
print(MyClass.instance_only == 'not anymore')  # True

# New instances will also have the attributes
new_instance = MyClass()
print(new_instance.new_attribute == 'added')  # True

如果您没有动态添加它们,请参阅@ gilch的回答

答案 1 :(得分:1)

实际上,最常见的用例是让他们拥有"拥有"实例之间不共享的变量("数据属性"在Python术语中)。下面的变量xy就是这样的"拥有"变量(类A的每个实例在调用构造函数时都会获得自己的变量x,而inst1也会在以后获得自己的变量y

class A():
    def __init__(self):     # Constructor - called when A is instantiated
        self.x = 10         # Creates x for self only (i.e. for each instance in turn)

inst1 = A()
inst1.x = 15                # Changes x for inst1 only
inst1.y = 20                # Creates y for inst1 only
print(inst1.x, inst1.y)     # 15 20

inst2 = A()
print(inst2.x)              # 10

答案 2 :(得分:0)

这取决于你是否在类的dict或实例的dict中设置变量。

>>> class A:
    var = 10


>>> inst1 = A()
>>> inst2 = A()
>>> inst1.var  # not in instance, so looked up in class
10
>>> inst2.var
10
>>> inst2.var = 20  # instance attr shadows that from class
>>> inst2.var
20
>>> A.var = 30  # class attr can also be altered
>>> inst1.var
30
>>> inst2.var
20
>>> del inst2.var  # deleting instance attr reveals shadowed class attr
>>> inst2.var
30
>>> inst1.var2 = 'spam'
>>> inst2.var2  # new attr was set on inst1, so not available in inst2
Traceback (most recent call last):
  File "<pyshell#663>", line 1, in <module>
    inst2.var2
AttributeError: 'A' object has no attribute 'var2'
>>> inst1.__class__.var3 = 'eggs'  # same as A.var3 = 'eggs'
>>> inst2.var3  # new attr was set on the class, so all instances see it.
'eggs'

答案 3 :(得分:0)

即使实际使用可能有问题,您实际上可以将新属性绑定到类定义,使其可用于该类的所有实例:

class A(object):
    attrib_one = 'VALUE'

    def add_class_attrib(self, name, value):
        # Bind new attribute to class definition, **not** to self
        setattr(A, name, value)

if __name__ == '__main__':
    # Instantiate _before_ changing A's class attributes
    a = A()
    b = A()
    # Add a new class attribute using only _one_ instance
    a.add_class_attrib('attrib_two', 'OTHER')
    # Print attributes of both instances
    print([e for e in dir(a) if not e.startswith('__')])
    print([e for e in dir(b) if not e.startswith('__')])

    # Create new instance _after_ changing A's class attribs
    c = A()
    # Print attributes of new instance
    print([e for e in dir(c) if not e.startswith('__')])

运行此代码将打印以下内容:

['add_class_attrib', 'attrib_one', 'attrib_two']
['add_class_attrib', 'attrib_one', 'attrib_two']
['add_class_attrib', 'attrib_one', 'attrib_two']

你看,即使属性被添加到类定义之后创建了它的一个实例,新创建的类属性也是如此事实可用于该(已更改)类的所有其他实例。