Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中如何在类中使用静态变量_Python_Python 3.x - Fatal编程技术网

在Python中如何在类中使用静态变量

在Python中如何在类中使用静态变量,python,python-3.x,Python,Python 3.x,我在学习python,我想要的是一个静态计数器,它计算类被实例化的次数,但是每次我创建一个实例时,counter都会被重新创建,count()函数总是返回1。 我想要在java中看起来像这样的东西 class Cls: counter = 0 def __init__(self, name): self.name = name self.counter += 1 def count(self): return self.co

我在学习python,我想要的是一个静态计数器,它计算类被实例化的次数,但是每次我创建一个实例时,
counter
都会被重新创建,
count()
函数总是返回1。 我想要在java中看起来像这样的东西

class Cls:
    counter = 0
    def __init__(self, name):
        self.name = name
        self.counter += 1
    def count(self):
        return self.counter

访问类属性有两种方法:可以直接在类上访问它,也可以通过
self
读取它(但不能重新绑定)。如果已经在实例上直接设置了值,那么通过
self
访问类属性将不起作用,因此您通常会尝试使用该类访问类属性

public class Cls {
    private static int counter = 0;
    private String name;
    public Cls(String name) {
        this.name = name;
        counter ++;
    }
    public static int count(){
        return counter;
    }
}
当您编写
self.counter+=1
时,这是
self.counter=self.counter+1
的简写,与通过
self
的任何其他绑定一样,它设置一个实例属性

public class Cls {
    private static int counter = 0;
    private String name;
    public Cls(String name) {
        this.name = name;
        counter ++;
    }
    public static int count(){
        return counter;
    }
}
如果您想要实例属性的默认值,可以将它们设置为类属性,然后只在需要不同值的实例中更新它们,但为了避免混淆,在访问类属性时可能根本不想使用
self

您还可以考虑将<代码>计数>代码>方法转换为类方法,并将增量移动到另一个方法:

class Cls:
    counter = 0
    def __init__(self, name):
        self.name = name
        Cls.counter += 1
    def count(self):
        return Cls.counter
如果这样做,那么每个子类都将有自己的独立计数器。这可能是你想要的,也可能不是。这里的
cls
参数是实际实例化的类,如果您可以创建一个完整的类层次结构,甚至只创建一个基类
CountsInstances
,您可以将此代码放置一次并与多个独立计数器一起重用,则此参数非常有用

使用
@staticmethod
装饰每个函数将使您获得接近Java代码的东西:

@classmethod
def increment(cls):
    cls.counter += 1

@classmethod
def count(cls):
    return cls.counter
不要使用Cls

class Cls:
    counter = 0
    def __init__(self, name):
        self.name = name
        self.increment()

    @staticmethod
    def increment():
        Cls.counter += 1

    @staticmethod
    def count():
        return Cls.counter
相反,您应该增加静态变量:

class MyClass:
    counter = 0
    def __init__(self, name):
        self.name = name
        self.counter += 1  # this creates an instance variable counter 
                           # thats initialized by counter if you do not set it
                           # it is NOT shared between instances, but specific to each 
如果你修好了

    def __init__(self, name):
        self.name = name
        MyClass.counter += 1  # this increments the static class variable  
这样,您仍然可以对实例以及直接对类调用count()

    @staticmethod
    def count():
        return MyClass.counter
输出:

t = MyClass("some")
print( MyClass.count() )  # fine

t1 = MyClass("other")
print( t.count() )        # only allowed if prefix the method with @staticmethod

有关更多信息,请参阅。

不要将Cls用作类名…Cls在Python中是一个保留字…只是说。@ma3oun
Cls
不是保留字,这仅仅是惯用语。这里值得一提的是类与静态方法之间的区别。相关的一点是,类方法可以选择性地让每个子类保留自己的计数器,而静态方法则强制所有子类共享一个计数器。再说一次,你已经解释了很多,所以可能额外的信息只会使OP过载?不确定,但这是你的答案,所以我不必确定@abarnert我稍微扩展了它,但我会让你的评论引导你:一旦你进入继承,这里可能会打开一个巨大的蠕虫罐头。我认为你找到了一个很好的平衡点,提出了这个问题,但没有陷入其中。我想如果你提到最后一节课的样子,解释会更容易理解和帮助比如…@AviC note我明白你的意思。修复方法是将
self.counter+=1
更改为
MyClass.counter+=1
,因此类计数器变量是递增的,而不是该值的实例副本。我提供了更改后的方法。在
count()
上使用
@staticmethod
进行的更改清楚地表明这将访问类变量。如果您继续使用
def count(self):return MyClass.counter
您“建议”将
count
作为类实例上的一个方法-但是您返回类变量,并且从不使用
self
访问实例的任何内容-因此这会让人感到困惑和有点欺骗。