是否可以在python中使用静态类变量或方法?这样做需要什么语法?
答案 0 :(得分:1681)
在类定义中声明但在方法内部未声明的变量是类或静态变量:
>>> 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#中,使用对实例的引用无法访问静态成员。
请参阅what the Python tutorial has to say on the subject of classes and class objects。
@Steve Johnson已经就static methods做出了回答,同时也记录在"Built-in Functions" in the Python Library Reference下。
class C:
@staticmethod
def f(arg1, arg2, ...): ...
@beidy推荐classmethod s over staticmethod,因为该方法接收类类型作为第一个参数,但我对这种方法相对于static方法的优势仍然有点模糊。如果你也是,那可能没关系。
答案 1 :(得分:561)
@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
上设置属性i
时,实例变量t
与“静态”类变量不同步。这是因为i
在t
命名空间内重新绑定,这与Test
命名空间不同。如果要更改“静态”变量的值,则必须在最初定义它的范围(或对象)内更改它。我把“静态”放在引号中,因为Python在C ++和Java的意义上并没有真正的静态变量。
虽然它没有说明有关静态变量或方法的任何具体内容,但Python tutorial在classes and class objects上有一些相关信息。
@Steve Johnson也回答了有关静态方法的问题,也在Python Library Reference中的“内置函数”中进行了记录。
class Test(object):
@staticmethod
def f(arg1, arg2, ...):
...
@beid还提到了classmethod,类似于staticmethod。 classmethod的第一个参数是类对象。例如:
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 the the same as Test.i = arg1
答案 2 :(得分:166)
正如其他答案所指出的那样,使用内置的装饰器很容易实现静态和类方法:
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()
,没有任何参数被绑定,并且根本没有参数是可选的。
然而,实施"静态变量" (好吧,可变的静态变量,无论如何,如果这不是一个矛盾......)并不是那么直截了当。作为millerdev pointed out in his answer,问题在于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
已向i
添加了新的实例属性x
,而不是更改Test
类i
属性的值。
部分预期的静态变量行为,即在多个实例之间同步属性(但不与类本身;请参阅"陷阱"以下),可以通过将class属性转换为属性来实现:
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
仍然不是一个静态变量'一点都没它是property
,是一种特殊类型的描述符。但是,property
行为现在等同于在所有类实例中同步的(可变)静态变量。
对于不可变的静态变量行为,只需省略property
setter:
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
会产生错误,因为i
和Test
的{{1}}属性是两个不同的对象。
许多人会发现这令人惊讶。但是,它不应该。如果我们返回并检查我们的x
类定义(第二个版本),我们会注意到这一行:
Test
显然, i = property(get_i)
的成员i
必须是Test
对象,这是从property
函数返回的对象类型。
如果您发现上述令人困惑,您很可能仍会从其他语言(例如Java或c ++)的角度考虑它。您应该研究property
对象,关于返回Python属性的顺序,描述符协议和方法解析顺序(MRO)。
我提出了上述问题的解决方案' gotcha'下面;但是我会建议 - 强烈地 - 你不要尝试做类似下面的事情,直到 - 至少 - 你完全理解为什么property
会导致错误。
assert Test.i = x.i
我在下面提供(Python 3)解决方案仅供参考。我不赞同它作为一个好的解决方案"。我怀疑是否真的需要在Python中模拟其他语言的静态变量行为。但是,无论它是否真的有用,下面应该有助于进一步理解Python的工作原理。
更新:此次尝试非常糟糕;如果你坚持做这样的事情(暗示:请不要; Python是一种非常优雅的语言,并且只是不需要像其他语言一样表现出来),请使用Ethan Furman's answer中的代码代替
使用元类
模拟其他语言的静态变量行为元类是类的类。 Python中所有类的默认元类(即#34;新样式"我认为的Python 2.3后的类)是Test.i == x.i
。例如:
type
但是,您可以像这样定义自己的元类:
type(int) # class 'type'
type(str) # class 'type'
class Test(): pass
type(Test) # class 'type'
并将它应用到您自己的类中(仅限Python 3):
class MyMeta(type): pass
下面是我创建的一个元类,它试图模拟"静态变量"其他语言的行为。它基本上可以通过用版本替换默认的getter,setter和deleter来工作,这些版本检查所请求的属性是否是静态变量"。
"静态变量的目录"存储在class MyClass(metaclass = MyMeta):
pass
type(MyClass) # class MyMeta
属性中。最初尝试使用替代分辨率顺序来解析所有属性请求。我将其称为"静态分辨率顺序"或" SRO"。这是通过在一组"静态变量"中查找所请求的属性来完成的。对于给定的类(或其父类)。如果该属性没有出现在" SRO"中,该类将回退到默认属性get / set / delete行为(即" MRO")。
StaticVarMeta.statics
答案 3 :(得分:24)
您还可以动态地将类变量添加到类
>>> 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]
答案 4 :(得分:15)
我个人在需要静态方法时会使用classmethod。主要是因为我把课作为论据。
class myObj(object):
def myMethod(cls)
...
myMethod = classmethod(myMethod)
或使用装饰
class myObj(object):
@classmethod
def myMethod(cls)
对于静态属性..它查找一些python定义的时间..变量总是可以改变。它们有两种类型,它们是可变的和不可变的。此外,还有类属性和实例属性。在java&amp; amp;意义上,没有什么比静态属性更像C ++
为什么在pythonic意义上使用静态方法,如果它对类没有任何关系!如果我是你,我要么使用classmethod,要么定义独立于类的方法。
答案 5 :(得分:13)
python中的静态方法称为classmethod s。看一下下面的代码
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 方法时,会出现错误。这是因为它要求在此类的实例上调用该方法。使用decorator @classmethod 将 myStaticMethod 方法设置为classmethod。
只是为了踢和笑,我们可以通过传入类的实例来调用类上的 myInstanceMethod ,如下所示:
>>> MyClass.myInstanceMethod(MyClass())
output from an instance method
答案 6 :(得分:13)
关于静态属性的一个特别注意事项&amp;实例属性,如下例所示:
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
这意味着在将值赋给instance属性之前,如果我们尝试通过'instance访问属性,则使用静态值。 在python类中声明的每个属性在内存中始终都有一个静态插槽。
答案 7 :(得分:8)
在任何成员方法之外定义某个成员变量时,该变量可以是静态变量,也可以是非静态变量,具体取决于变量的表达方式。
例如:
#!/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
答案 8 :(得分:6)
可能有static
个类变量,但可能不值得努力。
这里是用Python 3编写的概念验证 - 如果任何确切的细节都是错误的,可以调整代码以匹配static variable
的任何意思:
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
答案 9 :(得分:6)
您还可以使用元类强制使用静态类。
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。
答案 10 :(得分:5)
关于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
在与特定实例无关的意义上是静态的,但值仍然取决于(类的)实例
答案 11 :(得分:4)
关于这个answer,对于常量静态变量,您可以使用描述符。这是一个例子:
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
有关描述符的更多信息,请查看this answer和官方文档HOWTO。
答案 12 :(得分:4)
绝对是的, 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"
答案 13 :(得分:3)
我找到的最好方法是使用另一个班级。您可以创建一个对象,然后在其他对象上使用它。
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
的类。
此类应显示静态var __success
(Private Static Var)。
tryIt
类代表我们需要使用的常规类。
现在我为一个标志(staticFlag
)创建了一个对象。该标志将作为对所有常规对象的引用发送。
所有这些对象都被添加到列表tryArr
。
此脚本结果:
False
False
False
False
False
True
True
True
True
True
答案 14 :(得分:3)
为了避免任何可能的混淆,我想对比静态变量和不可变对象。
一些原始对象类型,如整数,浮点数,字符串和操作,在Python中是不可变的。这意味着如果给定名称引用的对象是上述对象类型之一,则该对象不能更改。可以将名称重新分配给其他对象,但不能更改对象本身。
使变量静态更进一步,不允许变量名指向任何对象,而是指向它当前指向的对象。 (注意:这是一般软件概念,并非特定于Python;有关在Python中实现静态的信息,请参阅其他人的帖子。)
答案 15 :(得分:2)
是的,绝对可以在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
静态方法:与变量类似,可以使用Name类直接访问静态方法。无需创建实例。
但是请记住,静态方法不能在python中调用非静态方法。
>>> class A:
... @staticmethod
... def my_static_method():
... print("Yippey!!")
...
>>> A.my_static_method()
Yippey!!
答案 16 :(得分:2)
所以这可能是黑客,但是我一直在使用eval(str)
在python 3中获取静态对象,有点矛盾。
有一个Records.py文件,除了class
对象之外,这些对象是用静态方法和保存一些参数的构造函数定义的。然后从另一个{.1} .py文件开始,但我需要动态选择每个对象,然后根据读取的数据类型按需实例化它。
因此,在import Records
或类名的地方,我叫object_name = 'RecordOne'
,然后实例化它,cur_type = eval(object_name)
但是,在实例化之前,您可以从cur_inst = cur_type(args)
调用静态方法,例如,类似于抽象基类的实现或目标是什么。但是在后端,它可能是在python中实例化的,并且不是真正的静态对象,因为eval返回的是一个对象……必须已经实例化……会产生类似静态的行为。
答案 17 :(得分:2)
@dataclass 定义提供用于定义实例变量和初始化方法 __init__()
的类级名称。如果您想在 @dataclass
中使用类级变量,您应该使用 typing.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)
答案 18 :(得分:1)
对于任何使用 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
答案 19 :(得分:1)
例如,如果您尝试共享静态变量,例如在其他实例之间增加静态变量,则类似此脚本的方法就可以正常工作:
# -*- coding: utf-8 -*-
class Worker:
id = 1
def __init__(self):
self.name = ''
self.document = ''
self.id = Worker.id
Worker.id += 1
def __str__(self):
return u"{}.- {} {}".format(self.id, self.name, self.document).encode('utf8')
class Workers:
def __init__(self):
self.list = []
def add(self, name, doc):
worker = Worker()
worker.name = name
worker.document = doc
self.list.append(worker)
if __name__ == "__main__":
workers = Workers()
for item in (('Fiona', '0009898'), ('Maria', '66328191'), ("Sandra", '2342184'), ('Elvira', '425872')):
workers.add(item[0], item[1])
for worker in workers.list:
print(worker)
print("next id: %i" % Worker.id)
答案 20 :(得分:1)
使用对象数据类型是可能的。但是像 bool
、int
、float
或 str
这样的原始类型的行为不同于其他 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
答案 21 :(得分:0)
只需创建一个包含任何变量的类 或对象类型。使用类访问该变量 名称如下:
class StaticVariable:
myvar1 = 1
myvar2 = 2
StaticVariable.myvar1 = StaticVariable.myvar1 +1
StaticVariable.myvar2 = StaticVariable.myvar2 +1
答案 22 :(得分:0)
您可以使用列表或字典来获取实例之间的“静态行为”。
if(width < 1100){
this.state = {
show: true
}
}
答案 23 :(得分:0)
通过这种方式,当用户定义的类存在时创建静态变量,并且定义静态变量时应在关键字self后面
import jenkins.model.Jenkins
import hudson.model.Job
MIN_BUILD_LOGS = 7
def sixMonthsAgo = new Date() - 180
Jenkins.instance.getAllItems(Job.class).each { job ->
println job.getFullDisplayName()
def recent = job.builds.limit(MIN_BUILD_LOGS)
def buildsToDelete = job.builds.findAll {
!recent.contains(it) && ! (it.getTime() > sixMonthsAgo)
}
if (!buildsToDelete) {
println "nothing to do"
}
for (build in buildsToDelete) {
println "Preparing to delete: " + build + build.getTime()
["bash", "-c", "rm -r " + build.getRootDir()].execute()
build.delete()
}
}
"done"
答案 24 :(得分:0)
与 @staticmethod
不同,但类变量是类的静态方法,并与所有实例共享。
现在你可以像访问它
instance = MyClass()
print(instance.i)
或
print(MyClass.i)
你必须给这些变量赋值
我正在努力
class MyClass:
i: str
并在一个方法调用中分配值,在这种情况下它将不起作用并且会抛出错误
i is not attribute of MyClass