2017-01-15 141 views
0

在Python中,是否可以訪問其設置器中的類變量的當前值訪問setter中屬性的當前值

例如:

# Getter 
@property 
# ... 

# Setter 
@position.setter 
def position(self, value): 
    # Do something with current value... 
    # self.position, self.__position, position and __position don't seem to work 

    # Update position with the given value 
    self.__position = value 

    # Do something with the new value... 

C#中的等價物是:

private Position position; 

public Position Position 
{ 
    get 
    { 
     // ... 
    } 

    set 
    { 
     // Do something with the current value... 

     // Update position field with given object 
     position = value; 

     // Do something with the new value... 
    } 
} 

更新
這裏是一個最小的,完整的和可驗證的例子來更好地說明我的問題:

class C: 
    def __init__(self): 
     self.x = 2 

    @property 
    def x(self): 
     return self.__x 

    @x.setter 
    def x(self, value): 
     print(self.x) 
     self.__x = value 
     print(self.x) 

c = C() 

以下引發錯誤:

AttributeError: 'C' object has no attribute '_C__x' 

這是因爲設定器試圖更新它之前打印該變量的當前值,並且當x被設置爲2的內部__init__設定器運行時,在該點x具有之前未分配一個值(沒有當前值可打印)。

+1

怎麼辦你的意思是*「似乎沒有工作」*?在你分配給它之前,'self .__ position'仍然是舊值,因此'self.position'也將訪問舊值。 – jonrsharpe

+0

這就是我在想的,但試圖在setter中訪問'self.position'或'self .__ position'都會導致以下錯誤:'AttributeError:'GameObject'對象沒有屬性'_GameObject__position''。 ('GameObject'是包含'position'變量的類。) – Ruben9922

+0

請給出[mcve]。另外考慮拋開'__double_underscore',因爲名字混亂不必要地使事情複雜化。 – jonrsharpe

回答

1

您在__init__中設置了self.x(使用setter)。但在你的x.setterprint(self.x)(使用getter)實際設置你的價值之前。

你可以定義一個默認值(例如,作爲class屬性),使其工作:

class C: 
    __x = None 

    def __init__(self): 
     self.x = 2 

    @property 
    def x(self): 
     return self.__x 

    @x.setter 
    def x(self, value): 
     print(self.x) 
     self.__x = value 
     print(self.x) 

>>> c = C() 
None 
2 

注意雙下劃線的變量都受到"name mangling"和會議是一個使用單下劃線的變量,而不是。

另一種方法是將try訪問它,如果它不繳費則返回別的東西(或做其他事):

class C: 
    def __init__(self): 
     self.x = 2 

    @property 
    def x(self): 
     try: 
      return self.__x 
     except AttributeError: 
      # I return "None" here but you could also do something else 
      return None 

    @x.setter 
    def x(self, value): 
     print(self.x) 
     self.__x = value 
     print(self.x) 

這將產生相同的結果:

>>> c = C() 
None 
2 
+0

只是想知道,是否有一種方法做到這一點,而不使變量「靜態」(沒有初始化__init__之外的'__x')? – Ruben9922

+0

@ Ruben9922我添加了另一種捕獲「getter」中的異常的方法。這是否回答你的問題?請注意,你也可以在你的setter中的第一個'print'語句周圍執行'try','except'。如果尚未設置任何屬性,可以跳過該步驟。 – MSeifert

+0

哦,好的。是的,這回答我的問題 - 謝謝! – Ruben9922