在Python中,有可能拥有静态类变量或方法吗?要做到这一点需要什么语法?
在类定义中声明的变量,但不在方法中的变量是类或静态变量。
>>> class MyClass:
... i = 3
...
>>> MyClass.i
3
正如@millerdev所指出的,这创建了一个类级的i
变量,但这与任何实例级的i
变量不同,所以你可以有
>>> m = MyClass()
>>> m.i = 4
>>> MyClass.i, m.i
>>> (3, 4)
这与C++和Java不同,但与C#差别不大,在C#中,静态成员不能使用对实例的引用来访问。
@Steve Johnson已经回答了关于静态方法的问题,在Python库参考文献中的"内置函数"中也有记载。
class C:
@staticmethod
def f(arg1, arg2, ...): ...
@beidy 推荐 classmethods 而不是 staticmethod,因为该方法会接收类的类型作为第一个参数,但我对这种方法比 staticmethod 的优势还是有点模糊。如果你也是这样,那么这可能并不重要。
@Blair Conrad说,在类定义里面声明的静态变量,但不是在方法里面声明的,是类或"静态"。 变量。
>>> class Test(object):
... i = 3
...
>>> Test.i
3
这里有几个Gotcha'。 继续上面的例子。
>>> t = Test()
>>> t.i # "static" variable accessed via instance
3
>>> t.i = 5 # but if we assign to the instance ...
>>> Test.i # we have not changed the "static" variable
3
>>> t.i # we have overwritten Test.i on t by creating a new attribute t.i
5
>>> Test.i = 6 # to change the "static" variable we do it by assigning to the class
>>> t.i
5
>>> Test.i
6
>>> u = Test()
>>> u.i
6 # changes to t do not affect new instances of Test
# Namespaces are one honking great idea -- let's do more of those!
>>> Test.__dict__
{'i': 6, ...}
>>> t.__dict__
{'i': 5}
>>> u.__dict__
{}
请注意实例变量t.i
如何与"static".类变量不同步。
类变量不同步的原因,当属性i
被直接设置在t
上时。
这是因为i
是在t
命名空间内重新绑定的,而t
命名空间与Test
命名空间是不同的。
如果你想改变一个"static"
变量的值,你必须在它最初定义的作用域(或对象)内改变它。
我把 "static"
加引号是因为 Python 并没有像 C++ 和 Java 那样真正意义上的静态变量。
虽然它没有说任何关于静态变量或方法的具体内容,但 Python 教程 有一些关于 类和类对象 的相关信息。
@Steve Johnson也回答了关于静态方法的问题,也在"内置函数" 下的静态方法。
class Test(object):
@staticmethod
def f(arg1, arg2, ...):
...
@beid还提到了classmethod,它和staticmethod类似。 类方法的第一个参数就是类对象。 例如:
class Test(object):
i = 3 # class (or static) variable
@classmethod
def g(cls, arg):
# here we can use 'cls' instead of the class name (Test)
if arg > cls.i:
cls.i = arg # would be the same as Test.i = arg1
class Test(object):
i = 3 # class (or static) variable
@classmethod
def g(cls, arg):
# here we can use 'cls' instead of the class name (Test)
if arg > cls.i:
cls.i = arg # would be the same as Test.i = arg1
[![上述实例的图解][1]][1]
正如其他答案所指出的那样,使用内置的装饰器可以轻松完成静态方法和类方法。
class Test(object):
# regular instance method:
def MyMethod(self):
pass
# class method:
@classmethod
def MyClassMethod(klass):
pass
# static method:
@staticmethod
def MyStaticMethod():
pass
像往常一样,"MyMethod() "的第一个参数被绑定到类实例对象上。
相反,MyClassMethod()
的第一个参数是绑定到类对象本身(例如,在本例中,Test
)。
对于MyStaticMethod()
来说,所有的参数都不被绑定,有参数是可选的。
然而,实现"静态变量"。 (好吧,反正是 mutable 静态变量,如果这不是术语上的矛盾的话......)并不是那么简单。 正如 millerdev [在他的回答中指出的][1],问题在于 Python'的类属性并不是真正的 "静态变量"。 考虑一下。
class Test(object):
i = 3 # This is a class attribute
x = Test()
x.i = 12 # Attempt to change the value of the class attribute using x instance
assert x.i == Test.i # ERROR
assert Test.i == 3 # Test.i was not affected
assert x.i == 12 # x.i is a different object than Test.i
这是因为行x.i = 12
给x
增加了一个新的实例属性i
,而不是改变Test
类i
属性的值。
部分预期的静态变量行为,即在多个实例之间同步属性(但*不与类本身。
见"gotcha"
下面),可以通过将类属性变成一个属性来实现。
class Test(object):
_i = 3
@property
def i(self):
return type(self)._i
@i.setter
def i(self,val):
type(self)._i = val
## ALTERNATIVE IMPLEMENTATION - FUNCTIONALLY EQUIVALENT TO ABOVE ##
## (except with separate methods for getting and setting i) ##
class Test(object):
_i = 3
def get_i(self):
return type(self)._i
def set_i(self,val):
type(self)._i = val
i = property(get_i, set_i)
现在你可以做。
x1 = Test()
x2 = Test()
x1.i = 50
assert x2.i == x1.i # no error
assert x2.i == 50 # the property is synced
静态变量现在将在所有类实例之间保持同步*。
(注意:除非一个类实例决定定义它自己版本的_i
!
也就是说,除非一个类实例决定定义它自己版本的_i
!
(注意:也就是说,除非类实例决定定义它自己版本的_i
!但是如果有人决定这样做,他们就应该得到他们所得到的,不是吗???)
注意,从技术上讲,i
仍然不是一个'静态变量'。
的静态变量。
它是一个属性
,是一种特殊类型的描述符。
然而,"属性 "行为现在相当于一个(可变)静态变量,在所有类实例中同步。
对于不可改变的静态变量行为,只需省略属性
设置器即可。
class Test(object):
_i = 3
@property
def i(self):
return type(self)._i
## ALTERNATIVE IMPLEMENTATION - FUNCTIONALLY EQUIVALENT TO ABOVE ##
## (except with separate methods for getting i) ##
class Test(object):
_i = 3
def get_i(self):
return type(self)._i
i = property(get_i)
现在试图设置实例i
属性将返回一个AttributeError
。
x = Test()
assert x.i == 3 # success
x.i = 12 # ERROR
请注意,上述方法只对你的类的个实例起作用--当使用类本身时,它们不会**起作用。 因此,例如
x = Test()
assert x.i == Test.i # ERROR
# x.i and Test.i are two different objects:
type(Test.i) # class 'property'
type(x.i) # class 'int'
"assert Test.i == x.i "这一行会产生一个错误,因为 "Test "和 "x "的 "i "属性是两个不同的对象。
很多人会觉得这很奇怪。
然而,这不应该是这样的。
如果我们回过头来检查一下我们的 Test
类定义 (第二个版本),我们会注意到这一行。
i = property(get_i)
显然,"Test "的成员i
必须是一个property
对象,也就是property
函数返回的对象类型。
如果你觉得上面的内容很混乱,那么你很可能还在从其他语言的角度考虑问题(如
Java或c++)的角度来考虑的。)
你应该去研究一下property
对象,关于Python属性的返回顺序,描述符协议,以及方法解析顺序(MRO)。
我介绍一个解决上述'疑难杂症&39的方法。
的解决方案。
然而,我强烈建议--至少在彻底理解为什么assert Test.i = x.i
会导致错误之前,不要尝试做类似下面的事情。
Test.i == x.i
##。我提出以下 (Python 3) 解决方案,仅供参考。
我并不认可它是一个"好的解决方案"。
我对在Python中模仿其他语言的静态变量行为是否真的有必要表示怀疑。
然而,不管它是否真的有用,下面的内容应该有助于进一步理解 Python 的工作原理。
更新。
这个尝试是非常可怕的。
如果你坚持要做这样的事情(提示:请不要';不要;;。
请不要'不要。
Python 是一门非常优雅的语言,用鞋子把它装成另一门语言的样子是没有必要的),请使用 [Ethan Furman's answer][2] 中的代码来代替。
使用元类模拟其他语言的静态变量行为。
元类是一个类的类。
在Python中所有类的默认元类(即"new style"
类在Python 2.3之后的类,我相信)是type
。
例如:{{5308775}}。
type(int) # class 'type'
type(str) # class 'type'
class Test(): pass
type(Test) # class 'type'
不过,你可以像这样定义自己的元类。
class MyMeta(type): pass
并将它应用到你自己的类中,就像这样 (仅限 Python 3)。
class MyClass(metaclass = MyMeta):
pass
type(MyClass) # class MyMeta
下面是我创建的一个元类,它试图模仿其他语言的"静态变量" 的行为。 基本上,它的工作原理是用检查被请求的属性是否是"静态变量"的版本来替换默认的getter、setter和deleter。
静态变量的目录"静态变量"。
存储在StaticVarMeta.statics
属性中。
所有的属性请求最初都会使用一个替代的解析顺序来尝试解析。
我将其称为"静态解析顺序",或"SRO"。
这是通过在"静态变量"集合中寻找请求的属性来实现的。
中寻找所需的属性。
如果该属性没有出现在"SRO"中,那么该类将回到默认的属性获取/设置/删除行为(即"MRO")。
from functools import wraps
class StaticVarsMeta(type):
'''A metaclass for creating classes that emulate the "static variable" behavior
of other languages. I do not advise actually using this for anything!!!
Behavior is intended to be similar to classes that use __slots__. However, "normal"
attributes and __statics___ can coexist (unlike with __slots__).
Example usage:
class MyBaseClass(metaclass = StaticVarsMeta):
__statics__ = {'a','b','c'}
i = 0 # regular attribute
a = 1 # static var defined (optional)
class MyParentClass(MyBaseClass):
__statics__ = {'d','e','f'}
j = 2 # regular attribute
d, e, f = 3, 4, 5 # Static vars
a, b, c = 6, 7, 8 # Static vars (inherited from MyBaseClass, defined/re-defined here)
class MyChildClass(MyParentClass):
__statics__ = {'a','b','c'}
j = 2 # regular attribute (redefines j from MyParentClass)
d, e, f = 9, 10, 11 # Static vars (inherited from MyParentClass, redefined here)
a, b, c = 12, 13, 14 # Static vars (overriding previous definition in MyParentClass here)'''
statics = {}
def __new__(mcls, name, bases, namespace):
# Get the class object
cls = super().__new__(mcls, name, bases, namespace)
# Establish the "statics resolution order"
cls.__sro__ = tuple(c for c in cls.__mro__ if isinstance(c,mcls))
# Replace class getter, setter, and deleter for instance attributes
cls.__getattribute__ = StaticVarsMeta.__inst_getattribute__(cls, cls.__getattribute__)
cls.__setattr__ = StaticVarsMeta.__inst_setattr__(cls, cls.__setattr__)
cls.__delattr__ = StaticVarsMeta.__inst_delattr__(cls, cls.__delattr__)
# Store the list of static variables for the class object
# This list is permanent and cannot be changed, similar to __slots__
try:
mcls.statics[cls] = getattr(cls,'__statics__')
except AttributeError:
mcls.statics[cls] = namespace['__statics__'] = set() # No static vars provided
# Check and make sure the statics var names are strings
if any(not isinstance(static,str) for static in mcls.statics[cls]):
typ = dict(zip((not isinstance(static,str) for static in mcls.statics[cls]), map(type,mcls.statics[cls])))[True].__name__
raise TypeError('__statics__ items must be strings, not {0}'.format(typ))
# Move any previously existing, not overridden statics to the static var parent class(es)
if len(cls.__sro__) > 1:
for attr,value in namespace.items():
if attr not in StaticVarsMeta.statics[cls] and attr != ['__statics__']:
for c in cls.__sro__[1:]:
if attr in StaticVarsMeta.statics[c]:
setattr(c,attr,value)
delattr(cls,attr)
return cls
def __inst_getattribute__(self, orig_getattribute):
'''Replaces the class __getattribute__'''
@wraps(orig_getattribute)
def wrapper(self, attr):
if StaticVarsMeta.is_static(type(self),attr):
return StaticVarsMeta.__getstatic__(type(self),attr)
else:
return orig_getattribute(self, attr)
return wrapper
def __inst_setattr__(self, orig_setattribute):
'''Replaces the class __setattr__'''
@wraps(orig_setattribute)
def wrapper(self, attr, value):
if StaticVarsMeta.is_static(type(self),attr):
StaticVarsMeta.__setstatic__(type(self),attr, value)
else:
orig_setattribute(self, attr, value)
return wrapper
def __inst_delattr__(self, orig_delattribute):
'''Replaces the class __delattr__'''
@wraps(orig_delattribute)
def wrapper(self, attr):
if StaticVarsMeta.is_static(type(self),attr):
StaticVarsMeta.__delstatic__(type(self),attr)
else:
orig_delattribute(self, attr)
return wrapper
def __getstatic__(cls,attr):
'''Static variable getter'''
for c in cls.__sro__:
if attr in StaticVarsMeta.statics[c]:
try:
return getattr(c,attr)
except AttributeError:
pass
raise AttributeError(cls.__name__ + " object has no attribute '{0}'".format(attr))
def __setstatic__(cls,attr,value):
'''Static variable setter'''
for c in cls.__sro__:
if attr in StaticVarsMeta.statics[c]:
setattr(c,attr,value)
break
def __delstatic__(cls,attr):
'''Static variable deleter'''
for c in cls.__sro__:
if attr in StaticVarsMeta.statics[c]:
try:
delattr(c,attr)
break
except AttributeError:
pass
raise AttributeError(cls.__name__ + " object has no attribute '{0}'".format(attr))
def __delattr__(cls,attr):
'''Prevent __sro__ attribute from deletion'''
if attr == '__sro__':
raise AttributeError('readonly attribute')
super().__delattr__(attr)
def is_static(cls,attr):
'''Returns True if an attribute is a static variable of any class in the __sro__'''
if any(attr in StaticVarsMeta.statics[c] for c in cls.__sro__):
return True
return False
[1]: https://stackoverflow.com/a/69067/2437514 [2]: https://stackoverflow.com/a/36216964/2437514
你也可以在飞行中向类中添加类变量。
>>> class X:
... pass
...
>>> X.bar = 0
>>> x = X()
>>> x.bar
0
>>> x.foo
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
AttributeError: X instance has no attribute 'foo'
>>> X.foo = 1
>>> x.foo
1
而类实例可以改变类变量
class X:
l = []
def __init__(self):
self.l.append(1)
print X().l
print X().l
>python test.py
[1]
[1, 1]
就我个人而言,只要我需要一个静态方法,我就会使用类方法。主要是因为我得到了类作为参数。
class myObj(object):
def myMethod(cls)
...
myMethod = classmethod(myMethod)
或者使用一个装饰器
class myObj(object):
@classmethod
def myMethod(cls)
对于静态属性...你应该查一下python的定义。它们有两种类型:可变的和不可变的。另外,还有类属性和实例属性。没有什么真正像java & c++意义上的静态属性。
如果它与类没有任何关系,为什么要使用pythonic意义上的静态方法呢?如果我是你,我要么使用classmethod,要么定义独立于类的方法。
python中的静态方法被称为classmethods。请看下面的代码
class MyClass:
def myInstanceMethod(self):
print 'output from an instance method'
@classmethod
def myStaticMethod(cls):
print 'output from a static method'
>>> MyClass.myInstanceMethod()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method myInstanceMethod() must be called [...]
>>> MyClass.myStaticMethod()
output from a static method
注意,当我们调用_myInstanceMethod_这个方法时,我们得到了一个错误。这是因为它要求该方法是在该类的一个实例上调用的。方法_myStaticMethod使用装饰器 @classmethod_被设置为类方法。
只是为了好玩,我们可以通过传入一个类的实例来调用myInstanceMethod,就像这样。
>> MyClass.myInstanceMethod(MyClass()
从一个实例方法中输出
关于静态属性&.有一点需要特别注意。 实例属性,如下例所示。
class my_cls:
my_prop = 0
#static property
print my_cls.my_prop #--> 0
#assign value to static property
my_cls.my_prop = 1
print my_cls.my_prop #--> 1
#access static property thru' instance
my_inst = my_cls()
print my_inst.my_prop #--> 1
#instance property is different from static property
#after being assigned a value
my_inst.my_prop = 2
print my_cls.my_prop #--> 1
print my_inst.my_prop #--> 2
这意味着在将值分配给实例属性之前,如果我们试图通过'.com访问该属性,将使用静态值。 实例,就会使用静态值。 在python类中声明的每个属性在内存中总是有一个静态槽。
当在任何成员方法之外定义一些成员变量时,变量可以是静态的,也可以是非静态的,这取决于变量的表达方式。
例如:
#!/usr/bin/python
class A:
var=1
def printvar(self):
print "self.var is %d" % self.var
print "A.var is %d" % A.var
a = A()
a.var = 2
a.printvar()
A.var = 3
a.printvar()
类内的成员函数var没有定义。
#!/usr/bin/python
class A:
var=1
def printvar(self):
print "self.var is %d" % self.var
print "A.var is %d" % A.var
a = A()
a.var = 2
a.printvar()
A.var = 3
a.printvar()
结果是
self.var is 2
A.var is 1
self.var is 2
A.var is 3
关于Python'的属性查找,有一点非常有趣,那就是它可以用来创建"virtual变量"。
class A(object):
label="Amazing"
def __init__(self,d):
self.data=d
def say(self):
print("%s %s!"%(self.label,self.data))
class B(A):
label="Bold" # overrides A.label
A(5).say() # Amazing 5!
B(3).say() # Bold 3!
通常在创建后不会对这些进行任何赋值。 请注意,查找使用了 "self",因为虽然 "label "是静态的,即不与某个实例相关联,但其值仍然取决于(实例的)类。
你也可以使用metaclass强制一个类成为静态的。
class StaticClassError(Exception):
pass
class StaticClass:
__metaclass__ = abc.ABCMeta
def __new__(cls, *args, **kw):
raise StaticClassError("%s is a static class and cannot be initiated."
% cls)
class MyClass(StaticClass):
a = 1
b = 3
@staticmethod
def add(x, y):
return x+y
然后每当你不小心尝试初始化MyClass时,你会得到一个StaticClassError。
有可能拥有静态
类变量,但可能不值得努力。
这里有一个用Python 3写的概念验证 -- 如果任何确切的细节是错误的,可以对代码进行调整,以符合你所说的 "静态变量"。
class Static:
def __init__(self, value, doc=None):
self.deleted = False
self.value = value
self.__doc__ = doc
def __get__(self, inst, cls=None):
if self.deleted:
raise AttributeError('Attribute not set')
return self.value
def __set__(self, inst, value):
self.deleted = False
self.value = value
def __delete__(self, inst):
self.deleted = True
class StaticType(type):
def __delattr__(cls, name):
obj = cls.__dict__.get(name)
if isinstance(obj, Static):
obj.__delete__(name)
else:
super(StaticType, cls).__delattr__(name)
def __getattribute__(cls, *args):
obj = super(StaticType, cls).__getattribute__(*args)
if isinstance(obj, Static):
obj = obj.__get__(cls, cls.__class__)
return obj
def __setattr__(cls, name, val):
# check if object already exists
obj = cls.__dict__.get(name)
if isinstance(obj, Static):
obj.__set__(name, val)
else:
super(StaticType, cls).__setattr__(name, val)
和使用中。
class MyStatic(metaclass=StaticType):
"""
Testing static vars
"""
a = Static(9)
b = Static(12)
c = 3
class YourStatic(MyStatic):
d = Static('woo hoo')
e = Static('doo wop')
和一些测试。
ms1 = MyStatic()
ms2 = MyStatic()
ms3 = MyStatic()
assert ms1.a == ms2.a == ms3.a == MyStatic.a
assert ms1.b == ms2.b == ms3.b == MyStatic.b
assert ms1.c == ms2.c == ms3.c == MyStatic.c
ms1.a = 77
assert ms1.a == ms2.a == ms3.a == MyStatic.a
ms2.b = 99
assert ms1.b == ms2.b == ms3.b == MyStatic.b
MyStatic.a = 101
assert ms1.a == ms2.a == ms3.a == MyStatic.a
MyStatic.b = 139
assert ms1.b == ms2.b == ms3.b == MyStatic.b
del MyStatic.b
for inst in (ms1, ms2, ms3):
try:
getattr(inst, 'b')
except AttributeError:
pass
else:
print('AttributeError not raised on %r' % attr)
ms1.c = 13
ms2.c = 17
ms3.c = 19
assert ms1.c == 13
assert ms2.c == 17
assert ms3.c == 19
MyStatic.c = 43
assert ms1.c == 13
assert ms2.c == 17
assert ms3.c == 19
ys1 = YourStatic()
ys2 = YourStatic()
ys3 = YourStatic()
MyStatic.b = 'burgler'
assert ys1.a == ys2.a == ys3.a == YourStatic.a == MyStatic.a
assert ys1.b == ys2.b == ys3.b == YourStatic.b == MyStatic.b
assert ys1.d == ys2.d == ys3.d == YourStatic.d
assert ys1.e == ys2.e == ys3.e == YourStatic.e
ys1.a = 'blah'
assert ys1.a == ys2.a == ys3.a == YourStatic.a == MyStatic.a
ys2.b = 'kelp'
assert ys1.b == ys2.b == ys3.b == YourStatic.b == MyStatic.b
ys1.d = 'fee'
assert ys1.d == ys2.d == ys3.d == YourStatic.d
ys2.e = 'fie'
assert ys1.e == ys2.e == ys3.e == YourStatic.e
MyStatic.a = 'aargh'
assert ys1.a == ys2.a == ys3.a == YourStatic.a == MyStatic.a
绝对是的 Python本身并没有明确的静态数据成员,但我们可以通过这样的方式来实现。
class A:
counter =0
def callme (self):
A.counter +=1
def getcount (self):
return self.counter
>>> x=A()
>>> y=A()
>>> print(x.getcount())
>>> print(y.getcount())
>>> x.callme()
>>> print(x.getcount())
>>> print(y.getcount())
产出
0
0
1
1
解释
here object (x) alone increment the counter variable
from 0 to 1 by not object y. But result it as "static counter"
关于这个答案,对于一个*常量的静态变量,你可以使用描述符。 这里有一个例子。
class ConstantAttribute(object):
'''You can initialize my value but not change it.'''
def __init__(self, value):
self.value = value
def __get__(self, obj, type=None):
return self.value
def __set__(self, obj, val):
pass
class Demo(object):
x = ConstantAttribute(10)
class SubDemo(Demo):
x = 10
demo = Demo()
subdemo = SubDemo()
# should not change
demo.x = 100
# should change
subdemo.x = 100
print "small demo", demo.x
print "small subdemo", subdemo.x
print "big demo", Demo.x
print "big subdemo", SubDemo.x
导致...
small demo 10
small subdemo 100
big demo 10
big subdemo 10
如果你不喜欢安静地忽略设置值(上面的pass
),你可以随时提出异常。
如果你正在寻找一个C++、Java风格的静态类变量。
class StaticAttribute(object):
def __init__(self, value):
self.value = value
def __get__(self, obj, type=None):
return self.value
def __set__(self, obj, val):
self.value = val
请看 [本回答][2] 和官方文档 [HOWTO][3] 了解更多关于描述符的信息。
1:
[2]: https://stackoverflow.com/a/102062/717357 [3]: https://docs.python.org/2/howto/descriptor.html
是的,绝对可以在python中编写静态变量和方法。
静态变量: 在类级声明的变量称为静态变量,可以直接使用类名来访问。
>>> class A:
...my_var = "shagun"
>>> print(A.my_var)
shagun
实例变量:与类的实例相关并被实例访问的变量为实例变量。
>>> a = A()
>>> a.my_var = "pruthi"
>>> print(A.my_var,a.my_var)
shagun pruthi
静态方法:类似于变量,静态方法可以直接使用类名访问。 不需要创建一个实例。
但要记住,静态方法不能调用python中的非静态方法。
>>> class A:
... @staticmethod
... def my_static_method():
... print("Yippey!!")
...
>>> A.my_static_method()
Yippey!!
我发现最好的方法是使用另一个类。 你可以创建一个对象,然后在其他对象上使用它。
class staticFlag:
def __init__(self):
self.__success = False
def isSuccess(self):
return self.__success
def succeed(self):
self.__success = True
class tryIt:
def __init__(self, staticFlag):
self.isSuccess = staticFlag.isSuccess
self.succeed = staticFlag.succeed
tryArr = []
flag = staticFlag()
for i in range(10):
tryArr.append(tryIt(flag))
if i == 5:
tryArr[i].succeed()
print tryArr[i].isSuccess()
通过上面的例子,我做了一个名为staticFlag
的类。
这个类应该呈现静态变量__success
(Private Static Var)。
tryIt
类代表我们需要使用的常规类。
现在我为一个标志(staticFlag
)做了一个对象。
这个标志将被作为引用发送给所有的常规对象。
所有这些对象将被添加到列表tryArr
中。
此脚本结果。
False
False
False
False
False
True
True
True
True
True
对于使用python3.6及以上版本的类工厂的人来说,使用nonlocal
关键字将其添加到正在创建的类的作用域/上下文中,例如:
>>> def SomeFactory(some_var=None):
... class SomeClass(object):
... nonlocal some_var
... def print():
... print(some_var)
... return SomeClass
...
>>> SomeFactory(some_var="hello world").print()
hello world
。
>>> def SomeFactory(some_var=None):
... class SomeClass(object):
... nonlocal some_var
... def print():
... print(some_var)
... return SomeClass
...
>>> SomeFactory(some_var="hello world").print()
hello world
你可以使用一个列表或一个字典来获取"静态行为"。 实例之间的行为。
class Fud:
class_vars = {'origin_open':False}
def __init__(self, origin = True):
self.origin = origin
self.opened = True
if origin:
self.class_vars['origin_open'] = True
def make_another_fud(self):
''' Generating another Fud() from the origin instance '''
return Fud(False)
def close(self):
self.opened = False
if self.origin:
self.class_vars['origin_open'] = False
fud1 = Fud()
fud2 = fud1.make_another_fud()
print (f"is this the original fud: {fud2.origin}")
print (f"is the original fud open: {fud2.class_vars['origin_open']}")
# is this the original fud: False
# is the original fud open: True
fud1.close()
print (f"is the original fud open: {fud2.class_vars['origin_open']}")
# is the original fud open: False