我想定义一个全局变量,该类的所有实例都可以访问(读取和写入)。我当前的解决方案显示在下面的示例中。我不喜欢在全局命名空间中使用变量,但是无法将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
答案 0 :(得分:4)
您的代码失败,因为您尝试在未正确声明的情况下访问全局变量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
答案 1 :(得分:2)
这是一种不需要任何全局变量的小巧方法。它利用了以下事实:默认参数仅在首次调用__init__
时创建一次,并且如果默认参数是可变的,则更改其中一个将影响同一类的所有将来函数/实例。
由于列表是可变的,因此我们可以将idx创建为列表,然后确保仅在适当位置修改该列表。这样做将确保Test
类的所有实例都指向完全相同的idx
列表。只要您只进行就地修改,更改一项就会全部更改。
class Test:
def __init__(self, idx = [0]):
self.idx = idx
def add(self):
self.idx[0] += 1
a = Test()
b = Test()
a.add()
print(a.idx, b.idx)
# >> Prints [1], [1]
答案 2 :(得分:1)
您可以使用单例模式来实现。这是一个单例的小例子:
class Singleton:
# Here will be the instance stored.
__instance = None
@staticmethod
def getInstance():
""" Static access method. """
if Singleton.__instance == None:
Singleton()
return Singleton.__instance
def add(self):
self.idx += 1
def __init__(self):
""" Virtually private constructor. """
if Singleton.__instance != None:
raise Exception("This class is a singleton!")
else:
Singleton.__instance = self
self.idx = 0
In [3]: main = Singleton()
In [4]: a = Singleton.getInstance()
In [5]: print(a.idx)
0
In [6]: a.add()
In [7]: print(a.idx)
1
In [8]: b = Singleton.getInstance()
In [9]: print(b.idx)
1
参考:https://www.tutorialspoint.com/python_design_patterns/python_design_patterns_singleton.htm
在SO上也有一些优雅的Singleton示例。
答案 3 :(得分:0)
您必须在方法之外的类中定义变量,并且该变量不得为自变量。自变量对于每个实例都是唯一的。 在方法中,必须使用类名来访问变量,否则该方法会将其视为私有变量,并且在大多数情况下,您会得到一个错误,因为它在使用前未初始化。
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)