簡體   English   中英

多個實例訪問的Python類變量

[英]Python class variable accessed by multiple instances

我想定義一個全局變量,該類的所有實例都可以訪問(讀取和寫入)。 我當前的解決方案顯示在下面的示例中。 我不喜歡在全局名稱空間中使用變量,但是無法將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 您需要訪問您的類變量。

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

這是一種不需要任何全局變量的小巧方法。 它利用了以下事實:默認參數僅在首次調用__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]

您可以使用單例模式來實現。 這是一個單例的小例子:

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示例。

您必須在方法之外的類中定義變量,並且該變量不得為自變量。 自變量對於每個實例都是唯一的。 在方法中,必須使用類名來訪問變量,否則該方法會將其視為私有變量,並且在大多數情況下,您會得到一個錯誤,因為在使用前未對其進行初始化。

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM