如何在Python中创建类(即静态)变量或方法?
当前回答
就我个人而言,每当我需要静态方法时,我都会使用类方法。主要是因为我把课堂当作一个论点。
class myObj(object):
def myMethod(cls)
...
myMethod = classmethod(myMethod)
或使用装饰器
class myObj(object):
@classmethod
def myMethod(cls)
对于静态财产。。是时候查一下python的定义了。。变量始终可以更改。有两种类型是可变的和不可变的。。此外,还有类属性和实例属性。。没有什么东西真正像java&c意义上的静态属性++
为什么要使用Python意义上的静态方法,如果它与类没有任何关系!如果我是你,我要么使用classmethod,要么定义独立于类的方法。
其他回答
使用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
您可以使用列表或字典来获取实例之间的“静态行为”。
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
@数据类定义提供用于定义实例变量和初始化方法__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)
当在任何成员方法之外定义某个成员变量时,该变量可以是静态的,也可以是非静态的,具体取决于该变量的表达方式。
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
@Blair Conrad表示,在类定义中声明的静态变量,而不是在方法中声明的是类或“静态”变量:
>>> class Test(object):
... i = 3
...
>>> Test.i
3
这里有几家餐厅。从以上示例继续:
>>> 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时,实例变量t.i如何与“static”类变量不同步。这是因为我在t命名空间中重新绑定,这与Test命名空间不同。如果要更改“静态”变量的值,必须在其最初定义的范围(或对象)内更改它。我把“static”放在引号里,因为Python实际上没有C++和Java那样的静态变量。
尽管Python教程没有具体说明静态变量或方法,但它提供了一些关于类和类对象的相关信息。
@Steve Johnson还回答了静态方法的问题,也在Python库参考中的“内置函数”中进行了记录。
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
推荐文章
- 如何使x轴和y轴的刻度相等呢?
- Numpy在这里函数多个条件
- 在Python中,使用argparse只允许正整数
- 如何排序mongodb与pymongo
- 不可变与可变类型
- 列表是线程安全的吗?
- 操作系统。makdirs在我的路径上不理解“~”
- 如何在Django模板中获得我的网站的域名?
- 在django Forms中定义css类
- 如何在Python中scp ?
- Numpy Max vs amax vs maximum
- 我应该在.gitignore文件中添加Django迁移文件吗?
- 每n行有熊猫
- 实例属性attribute_name定义在__init__之外
- 如何获取在Python中捕获的异常的名称?