如何在Python中创建类(即静态)变量或方法?
当前回答
当在任何成员方法之外定义某个成员变量时,该变量可以是静态的,也可以是非静态的,具体取决于该变量的表达方式。
CLASSNAME.var是静态变量INSTANCENAME.var不是静态变量。类内部的self.var不是静态变量。未定义类成员函数内的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
其他回答
类变量并允许子类化
假设你不是在寻找一个真正的静态变量,而是一个类似于蟒蛇的东西,它可以为同意的成年人做同样的工作,那么就使用一个类变量。这将为您提供一个所有实例都可以访问(和更新)的变量
注意:其他许多使用类变量的答案都会破坏子类化。应避免直接按名称引用类。
from contextlib import contextmanager
class Sheldon(object):
foo = 73
def __init__(self, n):
self.n = n
def times(self):
cls = self.__class__
return cls.foo * self.n
#self.foo * self.n would give the same result here but is less readable
# it will also create a local variable which will make it easier to break your code
def updatefoo(self):
cls = self.__class__
cls.foo *= self.n
#self.foo *= self.n will not work here
# assignment will try to create a instance variable foo
@classmethod
@contextmanager
def reset_after_test(cls):
originalfoo = cls.foo
yield
cls.foo = originalfoo
#if you don't do this then running a full test suite will fail
#updates to foo in one test will be kept for later tests
将为您提供与使用Sheldon.foo处理变量相同的功能,并将通过以下测试:
def test_times():
with Sheldon.reset_after_test():
s = Sheldon(2)
assert s.times() == 146
def test_update():
with Sheldon.reset_after_test():
s = Sheldon(2)
s.updatefoo()
assert Sheldon.foo == 146
def test_two_instances():
with Sheldon.reset_after_test():
s = Sheldon(2)
s3 = Sheldon(3)
assert s.times() == 146
assert s3.times() == 219
s3.updatefoo()
assert s.times() == 438
它还允许其他人简单地:
class Douglas(Sheldon):
foo = 42
这也将起作用:
def test_subclassing():
with Sheldon.reset_after_test(), Douglas.reset_after_test():
s = Sheldon(2)
d = Douglas(2)
assert d.times() == 84
assert s.times() == 146
d.updatefoo()
assert d.times() == 168 #Douglas.Foo was updated
assert s.times() == 146 #Seldon.Foo is still 73
def test_subclassing_reset():
with Sheldon.reset_after_test(), Douglas.reset_after_test():
s = Sheldon(2)
d = Douglas(2)
assert d.times() == 84 #Douglas.foo was reset after the last test
assert s.times() == 146 #and so was Sheldon.foo
有关创建课程时要注意的事项的最佳建议,请查看Raymond Hettinger的视频https://www.youtube.com/watch?v=HTLu2DFOdTg
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使用decorator@classmethod设置为类方法。
为了好玩,我们可以通过传入类的实例来调用类上的myInstanceMethod,如下所示:
>>> MyClass.myInstanceMethod(MyClass())
output from an instance method
就我个人而言,每当我需要静态方法时,我都会使用类方法。主要是因为我把课堂当作一个论点。
class myObj(object):
def myMethod(cls)
...
myMethod = classmethod(myMethod)
或使用装饰器
class myObj(object):
@classmethod
def myMethod(cls)
对于静态财产。。是时候查一下python的定义了。。变量始终可以更改。有两种类型是可变的和不可变的。。此外,还有类属性和实例属性。。没有什么东西真正像java&c意义上的静态属性++
为什么要使用Python意义上的静态方法,如果它与类没有任何关系!如果我是你,我要么使用classmethod,要么定义独立于类的方法。
是的,绝对可以在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!!
@数据类定义提供用于定义实例变量和初始化方法__init__()的类级名称。如果要在@dataclass中使用类级变量,则应使用typeing.ClassVar类型提示。ClassVar类型的参数定义类级别变量的类型。
from typing import ClassVar
from dataclasses import dataclass
@dataclass
class Test:
i: ClassVar[int] = 10
x: int
y: int
def __repr__(self):
return f"Test({self.x=}, {self.y=}, {Test.i=})"
用法示例:
> test1 = Test(5, 6)
> test2 = Test(10, 11)
> test1
Test(self.x=5, self.y=6, Test.i=10)
> test2
Test(self.x=10, self.y=11, Test.i=10)
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录