当前位置:  开发笔记 > 编程语言 > 正文

静态类变量是否可能?

如何解决《静态类变量是否可能?》经验,为你挑选了13个好方法。

是否有可能在python中有静态类变量或方法?这样做需要什么语法?



1> Blair Conrad..:

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

>>> 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 Library Reference中的"内置函数"中进行了介绍.

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

@beidy建议使用类方法而不是static 方法,因为该方法接收类类型作为第一个参数,但我对这种方法相对于静态方法的优势仍然有点模糊.如果你也是,那么它可能并不重要.


@theJollySin常量的pythonic方法是不为常量增长一个类.只需要一些带有`PI = 3.14`的`const.py`,你就可以在任何地方导入它.`来自const import PI`
这个答案可能会混淆静态变量问题.首先,`i = 3`是***不是***一个静态变量,它是一个类属性,因为它不同于实例级属性`i`它确实***不***在其他语言中表现得像一个静态变量.请参阅[millerdev的回答](http://stackoverflow.com/a/69067/2437514),[Yann的回答](http://stackoverflow.com/a/24553443/2437514)和[我的回答](http:/ /stackoverflow.com/a/27568860/2437514)下面.
我只是学习Python,但`@ classmethod`优于`@ staticmethod` AFAIK的优点是你总是得到调用该方法的类的名称,即使它是一个子类.例如,静态方法缺少此信息,因此无法调用重写方法.
所以即使我创建了这个类的数百个实例,只有一个`i`(静态变量)的副本会在内存中?
对于任何感兴趣的人,丹尼尔在@Dubslow评论中提到过,这是[millerdev](/sf/ask/17360801/#answer-69067)([wayback machine](https ://web.archive.org/web/20121023104030//sf/ask/17360801/))

2> millerdev..:

@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属性时实例变量与"static"类变量的同步.这是因为在命名空间内重新绑定,这与命名空间不同.如果要更改"静态"变量的值,则必须在最初定义它的范围(或对象)内更改它.我把"静态"放在引号中,因为Python在C++和Java的意义上并没有真正的静态变量.ititTest

虽然它没有说明有关静态变量或方法的任何内容,但Python教程提供了有关类和类对象的一些相关信息.

@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 be the same as Test.i = arg1

以上示例的图示表示


我建议你稍微扩展一下这个例子:如果在设置Test.i = 6后,然后实例化一个新对象(例如,u = Test()),新对象将"继承"新的类值(例如, UI == 6)
保持静态变量同步的一种方法是使它们成为属性:`class Test(object):`,`_ i = 3`,`@ property`,`def i(self)`,`return type(self). _i`,`@ i.setter`,`def i(self,val):`,`type(self)._ i = val`.现在你可以做`x = Test()`,`xi = 12`,`assert xi == Test.i`.

3> Rick support..:

静态和类方法

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

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添加了一个新的实例属性i,x而不是更改Testclass i属性的值.

部分预期的静态变量行为,即多个实例之间的属性同步(但与类本身同步;请参阅下面的"gotcha"),可以通过将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行为现在等效于在所有类实例中同步的(可变)静态变量.

不可变的"静态变量"

对于不可变的静态变量行为,只需省略propertysetter:

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对象,该对象是对象的从返回的类型property的功能.

如果您发现上述情况令人困惑,您很可能仍会从其他语言(例如Java或c ++)的角度考虑它.您应该研究property对象,返回Python属性的返回顺序,描述符协议和方法解析顺序(MRO).

我提出了以下'gotcha'的解决方案; 但是我会建议 - 强烈地 - 你不要尝试做以下事情,直到 - 至少 - 你彻底明白为什么assert Test.i = x.i会导致错误.

REAL,ACTUAL静态变量 -Test.i == x.i

我在下面提供(Python 3)解决方案仅供参考.我并不赞同它是一个"好的解决方案".我怀疑是否真的需要在Python中模拟其他语言的静态变量行为.但是,无论它是否真的有用,下面应该有助于进一步理解Python的工作原理.

更新:这次尝试非常糟糕 ; 如果你坚持做这样的事情(提示:请不要; Python是一种非常优雅的语言,并且只是不需要像其他语言一样表现出来),请使用Ethan Furman的答案中的代码.

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

元类是类的类.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和deleter来工作,这些版本检查被请求的属性是否是"静态变量".

"静态变量"的目录存储在StaticVarMeta.statics属性中.最初尝试使用替代分辨率顺序来解析所有属性请求.我把它称为"静态分辨率顺序"或"SRO".这是通过在给定类(或其父类)的"静态变量"集中查找所请求的属性来完成的.如果该属性未出现在"SRO"中,则该类将回退到默认属性get/set/delete行为(即"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



4> Gregory..:

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

>>> class X:
...     pass
... 
>>> X.bar = 0
>>> x = X()
>>> x.bar
0
>>> x.foo
Traceback (most recent call last):
  File "", line 1, in 
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]


即使将类导入另一个模块,新类变量是否仍然存在?

5> emb..:

我个人在需要静态方法时会使用classmethod.主要是因为我把课程作为一个论点.

class myObj(object):
   def myMethod(cls)
     ...
   myMethod = classmethod(myMethod) 

或使用装饰

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

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

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



6> willurd..:

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 "", line 1, in 
TypeError: unbound method myInstanceMethod() must be called [...]

>>> MyClass.myStaticMethod()
output from a static method

请注意,当我们调用方法myInstanceMethod时,我们会收到错误.这是因为它要求在此类的实例上调用该方法.方法myStaticMethod使用装饰器 @classmethod设置为classmethod .

只是为了踢和傻笑,我们可以通过传入类的实例来调用类上的myInstanceMethod,如下所示:

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



7> jondinham..:

有关静态属性和实例属性的一个特别注意事项,如下例所示:

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



8> 小智..:

在任何成员方法之外定义某个成员变量时,该变量可以是静态的也可以是非静态的,具体取决于表达变量的方式.

CLASSNAME.var是静态变量

INSTANCENAME.var不是静态变量.

class中的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



9> Bartosz Ptas..:

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

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.


如果你不打算实例化它,为什么它甚至是一个类?这就像扭曲Python将其变成Java一样....

10> Ethan Furman..:

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



11> Davis Herrin..:

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



12> Yann..:

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

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

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


您也可以只使用`@ property`,它与使用描述符相同,但是代码少得多。

13> Mari Selvan..:

绝对可以,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"

推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有