如何在Python中创建类(即静态)变量或方法?
当前回答
是的,绝对可以在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 myObj(object):
def myMethod(cls)
...
myMethod = classmethod(myMethod)
或使用装饰器
class myObj(object):
@classmethod
def myMethod(cls)
对于静态财产。。是时候查一下python的定义了。。变量始终可以更改。有两种类型是可变的和不可变的。。此外,还有类属性和实例属性。。没有什么东西真正像java&c意义上的静态属性++
为什么要使用Python意义上的静态方法,如果它与类没有任何关系!如果我是你,我要么使用classmethod,要么定义独立于类的方法。
为了避免任何潜在的混淆,我想对比静态变量和不可变对象。
一些基本对象类型,如整数、浮点数、字符串和元组,在Python中是不可变的。这意味着由给定名称引用的对象如果属于上述对象类型之一,则不能更改。可以将名称重新分配给不同的对象,但不能更改对象本身。
通过禁止变量名指向除当前指向的对象之外的任何对象,使变量成为静态变量更进一步。(注意:这是一个通用的软件概念,并不特定于Python;请参阅其他人的帖子,了解有关在Python中实现静态的信息)。
您还可以使用元类强制类为静态类。
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。
关于静态财产和实例财产,需要注意一件特殊的事情,如下例所示:
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
这意味着在将值分配给实例属性之前,如果我们试图通过“实例”访问属性,则使用静态值。python类中声明的每个属性在内存中总是有一个静态槽。
使用Object数据类型是可能的。但是对于bool、int、float或str等原始类型,bahaviour与其他OOP语言不同。因为在继承类中不存在静态属性。若继承类中不存在该属性,Python将开始在父类中查找该属性。如果在父类中找到,将返回其值。当您决定更改继承类中的值时,将在运行时创建静态属性。在下一次读取继承的静态属性时,将返回其值,因为它已经定义。对象(列表、字典)用作引用,因此可以安全地将它们用作静态属性并继承它们。对象地址在更改其属性值时不会更改。
整数数据类型示例:
class A:
static = 1
class B(A):
pass
print(f"int {A.static}") # get 1 correctly
print(f"int {B.static}") # get 1 correctly
A.static = 5
print(f"int {A.static}") # get 5 correctly
print(f"int {B.static}") # get 5 correctly
B.static = 6
print(f"int {A.static}") # expected 6, but get 5 incorrectly
print(f"int {B.static}") # get 6 correctly
A.static = 7
print(f"int {A.static}") # get 7 correctly
print(f"int {B.static}") # get unchanged 6
基于refdatatypes库的解决方案:
from refdatatypes.refint import RefInt
class AAA:
static = RefInt(1)
class BBB(AAA):
pass
print(f"refint {AAA.static.value}") # get 1 correctly
print(f"refint {BBB.static.value}") # get 1 correctly
AAA.static.value = 5
print(f"refint {AAA.static.value}") # get 5 correctly
print(f"refint {BBB.static.value}") # get 5 correctly
BBB.static.value = 6
print(f"refint {AAA.static.value}") # get 6 correctly
print(f"refint {BBB.static.value}") # get 6 correctly
AAA.static.value = 7
print(f"refint {AAA.static.value}") # get 7 correctly
print(f"refint {BBB.static.value}") # get 7 correctly