如何在Python中创建类(即静态)变量或方法?


当前回答

与@staticmethod不同,但类变量是类的静态方法,并与所有实例共享。

现在您可以像这样访问它

instance = MyClass()
print(instance.i)

or

print(MyClass.i)

必须为这些变量赋值

我在努力

class MyClass:
  i: str

并在一个方法调用中赋值,在这种情况下,它将不起作用,并将抛出错误

i is not attribute of MyClass

其他回答

您还可以向类动态添加类变量

>>> 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 MyClass:
...     i = 3
...
>>> MyClass.i
3 

正如@millerdev所指出的,这会创建一个类级别i变量,但这与任何实例级别i变量都不同,因此您可以

>>> m = MyClass()
>>> m.i = 4
>>> MyClass.i, m.i
>>> (3, 4)

这与C++和Java不同,但与C#没有太大区别,在C#中,不能使用对实例的引用来访问静态成员。

看看Python教程对类和类对象的主题有什么看法。

@Steve Johnson已经回答了静态方法的问题,也在Python库参考中的“内置函数”中进行了说明。

class C:
    @staticmethod
    def f(arg1, arg2, ...): ...

@beidy推荐classmethods而不是staticmethod,因为该方法随后会接收类类型作为第一个参数。

关于这个答案,对于常量静态变量,可以使用描述符。下面是一个示例:

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

如果您不喜欢忽略设置值(上面的传递),您总是可以引发异常。如果您正在寻找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

请查看此答案和HOWTO官方文件,以了解有关描述符的更多信息。

关于Python的属性查找,一个非常有趣的点是它可以用来创建“虚拟变量”:

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,因为尽管标签在不与特定实例关联的意义上是静态的,但值仍然取决于(的类)实例。

类工厂python3.6中的静态变量

对于使用python3.6及更高版本的类工厂的任何人,请使用非本地关键字将其添加到正在创建的类的作用域/上下文中,如下所示:

>>> 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