获取静态变量值
我试图创建一个静态变量,通过不同的类访问,赋值给它,并在需要时获取这个值。 为了实现这一目的,我确实使用了这种方式,这导致我包含一个属性如下:
class GetPartition(Partition):
_i = 100
def __init__(self):
super(Partition,self).__init__("get")
def get_i(self):
return type(self)._i
def set_i(self,val):
type(self)._i = val
i = property(get_i, set_i)
这是类Partition
如果需要:
class Partition(BaseCommand):
def __init__(self,type):
super(Partition,self).__init__("databaseTest")
self.type = type
因此,值分配给当i
从另一个类,我喜欢直接分配给它:
GetPartition.i = 5
并且在打印GetPartition.i
时,在这个类中它给了我5
,但是当试图从另一个类获得这个值时:
partitionNum = GetPartition()
print(partitionNum.i) # 100
print(partitionNum.get_i()) # 100
print(GetPartition.i) # <property object at 0x12A938D0>
print(GetPartition._i) # 100
正如我在我的评论中解释的那样,当您通过以下方式将5分配给i
时,问题就出现了:
GetPartition.i = 5
用这行代码,你覆盖了属性 ,并“绕过”属性设置器。 我的意思是:当您从类中调用属性名称时,属性设置器不会被调用; 它只在你从一个类实例中调用它的属性名称时被调用。
由于它已被覆盖,该属性不再存在,并且所有对i
属性的引用(无论是来自类实例还是来自类本身)都是不同的。 他们将不再检索相同的对象,而是检索不同的对象。
您可以通过执行此操作来确认此问题:
gp = GetPartition()
print(GetPartition.i) # the property is returned
GetPartition.i = 5 # here the property is overwritten
print(GetPartition.i) # 5 ; the property is gone
print(gp.i) # 5 because gp instance doesn't have its own i
gp.i = 2 # now gp does have its own i
print(gp.i) # 2
print(GetPartition.i) # 5 ; i is not synced
正如我上面所说的, property
getter和setter(以及一般的描述符)只能用于GetPartition
实例,而不是类本身。 他们可能会被迫通过创建一个类类metaclass(这是一个类的类)为你的类工作; 这被许多人认为是“深黑魔法”,如果你能避免这种情况,我不建议你走这条路。
我相信下面的例子可能是实现你想要的行为的最简单的方法。 这种方法放弃使用属性,而是直接重写属性getter和setter方法:
class Example():
i = 1 # this is a "static variable"
j = 3 # this is a regular class attribute
#designate which of the class attributes are "static"
statics = {'i'}
def __getattribute__(self, attr):
'''Overrides default attribute retrieval behavior.'''
if attr in Example.statics:
#use class version if attr is a static var
return getattr(Example, attr)
else:
#default behavior if attr is not static var
return super().__getattribute__(attr)
def __setattr__(self, attr, value):
'''Overrides default attribute setting behavior.'''
if attr in Example.statics:
#use class version if attr is a static var
setattr(Example, attr, value)
else:
#default behavior if attr is not static var
super().__setattr__(attr, value)
#testing
if __name__ == '__main__':
print("nnBEGIN TESTINGnn")
e = Example()
#confirm instance and class versions of i are the same
test = "assert e.i is Example.i"
exec(test)
print(test)
e.i = 5
#confirm they remain the same after instance change
test = "assert e.i is Example.i"
exec(test)
print(test)
Example.i = 100
#confirm they remain the same after class change
test = "assert e.i is Example.i"
exec(test)
print(test)
e.j = 12
#confirm both versions of j are distinct
test = "assert e.j is not Example.j"
exec(test)
print(test)
print("nnTESTING COMPLETEnn")
如果你对__getattribute__
和__setattr__
不熟悉,我应该让你知道,覆盖它们通常是非常危险的,并且会导致很大的问题(尤其是__getattribute__
)。 你会发现许多人只是说:“不要这样做;重新思考你的问题,找到另一种解决方案”。 正确覆盖需要深入理解各种python主题。
我没有声称有这个深刻的理解(虽然我认为我有一个很好的理解),所以我不能100%确定我的覆盖如上所述不会导致你的其他问题。 我相信它们很健全,但要注意Python的这些特殊角落可能会非常棘手。
链接地址: http://www.djcxy.com/p/13811.html上一篇: Get static variable value
下一篇: How is heap and stack memories managed, implemented, allocated?