python 中是否可以有静态类变量或方法?执行此操作需要什么语法?

有帮助吗?

解决方案

在类定义内部但不在方法内部声明的变量是类变量或静态变量:

>>> class MyClass:
...     i = 3
...
>>> MyClass.i
3 

作为 @米勒德夫 指出,这创建了一个类级别 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推荐 类方法s 优于 staticmethod,因为该方法随后接收类类型作为第一个参数,但我仍然对这种方法相对于 staticmethod 的优点有点模糊。如果你也是,那么这可能并不重要。

其他提示

@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 命名空间。如果要更改“静态”变量的值,则必须在其最初定义的范围(或对象)内更改它。我将“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 the the same as  Test.i = arg1

Pictorial Representation Of Above Example

静态和类方法

正如其他答案所指出的,使用内置装饰器可以轻松完成静态和类方法:

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(), ,没有一个参数是绑定的,并且有参数是可选的。

“静态变量”

然而,实现“静态变量”(嗯, 可变的 无论如何,静态变量,如果这在术语上不矛盾的话......)并不那么简单。正如米勒德夫 他在回答中指出, ,问题在于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 添加了新的实例属性 ix 而不是改变的值 Test 班级 i 属性。

部分的 预期的静态变量行为,即在多个实例之间同步属性(但是 不是 与班级本身;参见下面的“陷阱”),可以通过将类属性转换为属性来实现:

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 设置者:

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 的属性 Testx 是两个不同的对象。

很多人会觉得这很奇怪。然而,事实并非如此。如果我们回去检查我们的 Test 类定义(第二个版本),我们记下这一行:

    i = property(get_i) 

显然,该会员 iTest 必须是一个 property object,这是从返回的对象类型 property 功能。

如果您发现上述内容令人困惑,您很可能仍在从其他语言的角度思考它(例如Java 或 C++)。你应该去学习 property 对象,有关 Python 属性返回的顺序、描述符协议和方法解析顺序 (MRO)。

我在下面提出了上述“陷阱”的解决方案;但是我强烈建议您不要尝试执行以下操作,直到您至少彻底理解原因 assert Test.i = x.i 导致错误。

真实的、实际的 静态变量 - Test.i == x.i

我在下面介绍(Python 3)解决方案仅供参考。我并不认可它是一个“好的解决方案”。我怀疑在 Python 中模拟其他语言的静态变量行为是否真的有必要。不过,不管它是否真的有用,下面的内容应该有助于进一步理解Python是如何工作的。

更新:这次尝试 真的很糟糕;如果你坚持做这样的事情(提示:请不要;Python 是一种非常优雅的语言,并没有必要强迫它表现得像另一种语言),请使用以下代码: 伊森·弗曼的回答 反而。

使用元类模拟其他语言的静态变量行为

元类是类的类。Python 中所有类的默认元类(即我相信 Python 2.3 后的“新样式”类)是 type. 。例如:

type(int)  # class 'type'
type(str)  # class 'type'
class Test(): pass
type(Test) # class 'type'

但是,您可以像这样定义自己的元类:

class MyMeta(type): pass

并将其应用到您自己的类中,如下所示(仅限 Python 3):

class MyClass(metaclass = MyMeta):
    pass

type(MyClass)  # class MyMeta

下面是我创建的一个元类,它尝试模拟其他语言的“静态变量”行为。它的工作原理基本上是用检查所请求的属性是否是“静态变量”的版本替换默认的 getter、setter 和删除器。

“静态变量”的目录存储在 StaticVarMeta.statics 属性。所有属性请求最初都尝试使用替代解析顺序来解析。我将其称为“静态决议令”或“SRO”。这是通过在给定类(或其父类)的“静态变量”集中查找所请求的属性来完成的。如果该属性未出现在“SRO”中,则该类将依赖于默认属性获取/设置/删除行为(即“MRO”)。

from functools import wraps

class StaticVarsMeta(type):
    '''A metaclass for creating classes that emulate the "static variable" behavior
    of other languages. I do not advise actually using this for anything!!!

    Behavior is intended to be similar to classes that use __slots__. However, "normal"
    attributes and __statics___ can coexist (unlike with __slots__). 

    Example usage: 

        class MyBaseClass(metaclass = StaticVarsMeta):
            __statics__ = {'a','b','c'}
            i = 0  # regular attribute
            a = 1  # static var defined (optional)

        class MyParentClass(MyBaseClass):
            __statics__ = {'d','e','f'}
            j = 2              # regular attribute
            d, e, f = 3, 4, 5  # Static vars
            a, b, c = 6, 7, 8  # Static vars (inherited from MyBaseClass, defined/re-defined here)

        class MyChildClass(MyParentClass):
            __statics__ = {'a','b','c'}
            j = 2  # regular attribute (redefines j from MyParentClass)
            d, e, f = 9, 10, 11   # Static vars (inherited from MyParentClass, redefined here)
            a, b, c = 12, 13, 14  # Static vars (overriding previous definition in MyParentClass here)'''
    statics = {}
    def __new__(mcls, name, bases, namespace):
        # Get the class object
        cls = super().__new__(mcls, name, bases, namespace)
        # Establish the "statics resolution order"
        cls.__sro__ = tuple(c for c in cls.__mro__ if isinstance(c,mcls))

        # Replace class getter, setter, and deleter for instance attributes
        cls.__getattribute__ = StaticVarsMeta.__inst_getattribute__(cls, cls.__getattribute__)
        cls.__setattr__ = StaticVarsMeta.__inst_setattr__(cls, cls.__setattr__)
        cls.__delattr__ = StaticVarsMeta.__inst_delattr__(cls, cls.__delattr__)
        # Store the list of static variables for the class object
        # This list is permanent and cannot be changed, similar to __slots__
        try:
            mcls.statics[cls] = getattr(cls,'__statics__')
        except AttributeError:
            mcls.statics[cls] = namespace['__statics__'] = set() # No static vars provided
        # Check and make sure the statics var names are strings
        if any(not isinstance(static,str) for static in mcls.statics[cls]):
            typ = dict(zip((not isinstance(static,str) for static in mcls.statics[cls]), map(type,mcls.statics[cls])))[True].__name__
            raise TypeError('__statics__ items must be strings, not {0}'.format(typ))
        # Move any previously existing, not overridden statics to the static var parent class(es)
        if len(cls.__sro__) > 1:
            for attr,value in namespace.items():
                if attr not in StaticVarsMeta.statics[cls] and attr != ['__statics__']:
                    for c in cls.__sro__[1:]:
                        if attr in StaticVarsMeta.statics[c]:
                            setattr(c,attr,value)
                            delattr(cls,attr)
        return cls
    def __inst_getattribute__(self, orig_getattribute):
        '''Replaces the class __getattribute__'''
        @wraps(orig_getattribute)
        def wrapper(self, attr):
            if StaticVarsMeta.is_static(type(self),attr):
                return StaticVarsMeta.__getstatic__(type(self),attr)
            else:
                return orig_getattribute(self, attr)
        return wrapper
    def __inst_setattr__(self, orig_setattribute):
        '''Replaces the class __setattr__'''
        @wraps(orig_setattribute)
        def wrapper(self, attr, value):
            if StaticVarsMeta.is_static(type(self),attr):
                StaticVarsMeta.__setstatic__(type(self),attr, value)
            else:
                orig_setattribute(self, attr, value)
        return wrapper
    def __inst_delattr__(self, orig_delattribute):
        '''Replaces the class __delattr__'''
        @wraps(orig_delattribute)
        def wrapper(self, attr):
            if StaticVarsMeta.is_static(type(self),attr):
                StaticVarsMeta.__delstatic__(type(self),attr)
            else:
                orig_delattribute(self, attr)
        return wrapper
    def __getstatic__(cls,attr):
        '''Static variable getter'''
        for c in cls.__sro__:
            if attr in StaticVarsMeta.statics[c]:
                try:
                    return getattr(c,attr)
                except AttributeError:
                    pass
        raise AttributeError(cls.__name__ + " object has no attribute '{0}'".format(attr))
    def __setstatic__(cls,attr,value):
        '''Static variable setter'''
        for c in cls.__sro__:
            if attr in StaticVarsMeta.statics[c]:
                setattr(c,attr,value)
                break
    def __delstatic__(cls,attr):
        '''Static variable deleter'''
        for c in cls.__sro__:
            if attr in StaticVarsMeta.statics[c]:
                try:
                    delattr(c,attr)
                    break
                except AttributeError:
                    pass
        raise AttributeError(cls.__name__ + " object has no attribute '{0}'".format(attr))
    def __delattr__(cls,attr):
        '''Prevent __sro__ attribute from deletion'''
        if attr == '__sro__':
            raise AttributeError('readonly attribute')
        super().__delattr__(attr)
    def is_static(cls,attr):
        '''Returns True if an attribute is a static variable of any class in the __sro__'''
        if any(attr in StaticVarsMeta.statics[c] for c in cls.__sro__):
            return True
        return False

您还可以动态地将类变量添加到类中

>>> 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 myObj(object):
   def myMethod(cls)
     ...
   myMethod = classmethod(myMethod) 

或者使用装饰器

class myObj(object):
   @classmethod
   def myMethod(cls)

对于静态属性..是时候查找一些 python 定义了..变量总是可以改变的。它们有两种类型:可变的和不可变的。此外,还有类属性和实例属性。从 java 和 c++ 的意义上来说,没有什么比静态属性更好的了

为什么要使用Python意义上的静态方法,如果它与类没有任何关系!如果我是你,我要么使用 classmethod,要么定义独立于类的方法。

关于静态属性和实例属性需要注意的一件特别的事情,如下例所示:

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 类中声明的每个属性在内存中始终有一个静态槽.

python中的静态方法被调用 类方法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

请注意,当我们调用该方法时 我的实例方法, ,我们得到一个错误。这是因为它要求在此类的实例上调用该方法。方法 我的静态方法 使用以下方法设置为类方法 装饰者 @类方法.

只是为了踢球和咯咯笑,我们可以打电话 我的实例方法 通过传入类的实例来访问该类,如下所示:

>>> MyClass.myInstanceMethod(MyClass())
output from an instance method

当在任何成员方法外部定义某些成员变量时,该变量可以是静态的或非静态的,具体取决于变量的表达方式。

  • 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

您还可以使用元类强制类为静态。

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

然后每当你不小心尝试初始化 我的课 你会得到一个 StaticClassError 。

有可能有 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

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 因为,虽然 label 静态是指不与某个对象相关联 特别的 实例,该值仍然取决于实例(的类)。

对此 回答, , 为一个 持续的 静态变量,可以使用描述符。这是一个例子:

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

看一下 这个答案 和官方文档 如何 有关描述符的更多信息。

绝对是的,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"

为了避免任何潜在的混淆,我想对比静态变量和不可变对象。

一些原始对象类型(例如整数、浮点数、字符串和元组)在 Python 中是不可变的。这意味着,如果给定名称引用的对象属于上述对象类型之一,则该对象不能更改。名称可以重新分配给不同的对象,但对象本身不能更改。

将变量设置为静态则更进一步,不允许变量名称指向除当前指向的对象之外的任何对象。(笔记:这是一个通用的软件概念,并非 Python 特有的;有关在 Python 中实现静态的信息,请参阅其他人的帖子)。

我发现最好的方法是使用另一个类。您可以创建一个对象,然后将其用于其他对象。

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.

这个类应该呈现静态变量 __success (私有静态变量)。

tryIt class 代表我们需要使用的常规类。

现在我为一个标志创建了一个对象(staticFlag)。该标志将作为所有常规对象的引用发送。

所有这些对象都被添加到列表中 tryArr.


该脚本结果:

False
False
False
False
False
True
True
True
True
True

是的,绝对可以在 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!!

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

对于任何使用类工厂的人 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

只需创建一个包含任何变量或对象类型的类。使用类似的类名称访问该变量:


    class StaticVariable:
        myvar1 = 1
        myvar2 = 2


    StaticVariable.myvar1 = StaticVariable.myvar1 +1
    StaticVariable.myvar2 = StaticVariable.myvar2 +1

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top