由多个实例访问的Python类变量

由多个实例访问的Python类变量,python,Python,我想定义一个全局变量,它可以被类的所有实例访问(读和写)。下面的示例显示了我当前的解决方案。我不喜欢在全局名称空间中有一个变量,但我无法将idx放入类中。我怎样才能把idx放在课堂上并达到同样的效果 # working idx = 0 class test(object): def add(self): global idx idx += 1 def print_x(self): global idx print(i

我想定义一个全局变量,它可以被类的所有实例访问(读和写)。下面的示例显示了我当前的解决方案。我不喜欢在全局名称空间中有一个变量,但我无法将
idx
放入类中。我怎样才能把
idx
放在课堂上并达到同样的效果

# working
idx = 0
class test(object):
    def add(self):
        global idx
        idx += 1
    def print_x(self):
        global idx
        print(idx)

test1 = test()
test1.add()
test1.print_x()
test2 = test()
test2.add()
test2.print_x()

# Error
class test(object):
    idx = 0
    def add(self):
        global idx
        idx += 1
    def print_x(self):
        global idx
        print(idx)

test1 = test()
test1.add()
test1.print_x()
test2 = test()
test2.add()
test2.print_x()

Traceback (most recent call last):
  File "test.py", line 16, in <module>
    test1.add()
  File "test.py", line 9, in add
    idx += 1
NameError: global name 'idx' is not defined
#正在工作
idx=0
类别测试(对象):
def添加(自我):
全球idx
idx+=1
def打印_x(自身):
全球idx
打印(idx)
test1=test()
test1.add()
test1.print_x()
test2=test()
test2.add()
test2.print_x()
#错误
类别测试(对象):
idx=0
def添加(自我):
全球idx
idx+=1
def打印_x(自身):
全球idx
打印(idx)
test1=test()
test1.add()
test1.print_x()
test2=test()
test2.add()
test2.print_x()
回溯(最近一次呼叫最后一次):
文件“test.py”,第16行,在
test1.add()
文件“test.py”,第9行,添加
idx+=1
NameError:未定义全局名称“idx”

您的代码失败,因为您试图访问全局变量
idx
,但没有正确声明它。您需要访问类变量

class Test(object):
    idx = 0
    def add(self):
        Test.idx += 1

obj = Test()
obj.add()
print(Test.idx)
obj = Test()
obj.add()
print(Test.idx)
输出:

1
2

您的代码失败,因为您试图访问全局变量
idx
,但没有正确声明它。您需要访问类变量

class Test(object):
    idx = 0
    def add(self):
        Test.idx += 1

obj = Test()
obj.add()
print(Test.idx)
obj = Test()
obj.add()
print(Test.idx)
输出:

1
2

您可以使用单例模式来实现这一点。下面是一个单例的小例子:

类单例:
#下面是存储的实例。
__实例=无
@静力学方法
def getInstance():
“”“静态访问方法。”“”
如果Singleton.\uuu实例==无:
Singleton()
返回Singleton.\u实例
def添加(自我):
self.idx+=1
定义初始化(自):
“”“虚拟私有构造函数。”“”
如果是单例无:
引发异常(“该类是单例!”)
其他:
Singleton.\uuu实例=self
self.idx=0
[3]中的
main=Singleton()
在[4]中:a=Singleton.getInstance()
In[5]:打印(a.idx)
0
在[6]中:a.add()
In[7]:打印(a.idx)
1.
在[8]中:b=Singleton.getInstance()
In[9]:打印(b.idx)
1.
参考:


还有一些优雅的单例示例。

您可以使用单例模式实现这一点。下面是一个单例的小例子:

类单例:
#下面是存储的实例。
__实例=无
@静力学方法
def getInstance():
“”“静态访问方法。”“”
如果Singleton.\uuu实例==无:
Singleton()
返回Singleton.\u实例
def添加(自我):
self.idx+=1
定义初始化(自):
“”“虚拟私有构造函数。”“”
如果是单例无:
引发异常(“该类是单例!”)
其他:
Singleton.\uuu实例=self
self.idx=0
[3]中的
main=Singleton()
在[4]中:a=Singleton.getInstance()
In[5]:打印(a.idx)
0
在[6]中:a.add()
In[7]:打印(a.idx)
1.
在[8]中:b=Singleton.getInstance()
In[9]:打印(b.idx)
1.
参考:


这里也有一些优雅的单例示例。

这里有一个不需要任何全局变量的简单方法。它利用了这样一个事实:当第一次调用
\uuuu init\uuuu
时,默认参数只创建一次,如果默认参数是可变的,那么更改其中一个参数将影响同一类的所有未来函数/实例

我们可以将idx创建为一个列表,因为列表是可变的,然后确保只在适当的位置修改该列表。这样做将确保
Test
类的所有实例都指向完全相同的
idx
列表。只要您只进行就地修改,更改一个即可更改所有内容

类测试:
定义初始化(self,idx=[0]):
self.idx=idx
def添加(自我):
self.idx[0]+=1
a=测试()
b=测试()
a、 添加()
打印(a.idx,b.idx)
#>>打印[1],[1]

这里有一个不需要任何全局变量的简单方法。它利用了这样一个事实:当第一次调用
\uuuu init\uuuu
时,默认参数只创建一次,如果默认参数是可变的,那么更改其中一个参数将影响同一类的所有未来函数/实例

我们可以将idx创建为一个列表,因为列表是可变的,然后确保只在适当的位置修改该列表。这样做将确保
Test
类的所有实例都指向完全相同的
idx
列表。只要您只进行就地修改,更改一个即可更改所有内容

类测试:
定义初始化(self,idx=[0]):
self.idx=idx
def添加(自我):
self.idx[0]+=1
a=测试()
b=测试()
a、 添加()
打印(a.idx,b.idx)
#>>打印[1],[1]

您必须在类中、方法之外定义变量,并且它不应是自变量。自变量对于每个实例都是唯一的。 在方法中,您必须使用类名来访问变量,否则该方法会将其视为私有变量,并且在大多数情况下,您会得到一个错误,因为它在使用之前没有初始化

class MyClass:
    my_public_variable = 0
    __my_private_variable = 5

    def inc(self):
        MyClass.my_public_variable += 1
        MyClass.__my_private_variable += 1

    def show(self):
        print(MyClass.my_public_variable)
        print(MyClass.__my_private_variable)

obj1 = MyClass()
obj1.show()

obj2 = MyClass()
obj2.show()

obj1.inc()
obj2.show()

print(obj1.my_public_variable)
print(obj1.my_private_variable) # Invokes error
通过运行此代码,将在不带括号的情况下打印出以下内容:

0  (my_public_variable of obj1)
5  (my_private_variable of obj1)
0  (my_public_variable of obj2)
5  (my_private_variable of obj2)
1  (my_public_variable of obj2, incremented by obj1)
6  (my_private_variable of obj2, incremented by obj1)
1  (my_public_variable of obj1, it can be accessed outside of the class, since it is a public variable of the class)
Error (because, as its name suggests, my_private_variable is a private variable of the class)

你必须在类中定义你的变量,在方法之外,它不应该是一个自变量。自变量对于每个实例都是唯一的。 在方法中,您必须使用类名来访问变量,否则该方法会将其视为私有变量,并且在大多数情况下,您会得到一个错误,因为它在使用之前没有初始化

class MyClass:
    my_public_variable = 0
    __my_private_variable = 5

    def inc(self):
        MyClass.my_public_variable += 1
        MyClass.__my_private_variable += 1

    def show(self):
        print(MyClass.my_public_variable)
        print(MyClass.__my_private_variable)

obj1 = MyClass()
obj1.show()

obj2 = MyClass()
obj2.show()

obj1.inc()
obj2.show()

print(obj1.my_public_variable)
print(obj1.my_private_variable) # Invokes error
通过运行此代码,将在不带括号的情况下打印出以下内容:

0  (my_public_variable of obj1)
5  (my_private_variable of obj1)
0  (my_public_variable of obj2)
5  (my_private_variable of obj2)
1  (my_public_variable of obj2, incremented by obj1)
6  (my_private_variable of obj2, incremented by obj1)
1  (my_public_variable of obj1, it can be accessed outside of the class, since it is a public variable of the class)
Error (because, as its name suggests, my_private_variable is a private variable of the class)

我想你想要一个
@classmethod
(虽然我在这里不太懂)。你说的“跟踪”到底是什么意思?