2013-07-16 136 views
1

我開始在python中創建類,我對這些術語感到困惑,所以我找不到我的問題的答案,因爲我不知道如何問這些,因此這個職位的雙重標題。我會嘗試澄清,我不知道如何提出用下面的代碼的問題:適用於python中類的實例的方法//將方法應用於python中的類的實例

我想創建一個簡單的類中的方法:

class SimpleClass: 
    add(self,Value) 
     #Magic goes here 

SC=SimpleClass() 

的方法應該是相當於增加一個新的變量到類:

SC.NewVariableInsideTheClass="test" 

但是通過一種方法,例如:

SC.NewVariableInsideTheClass.add("test") 

在這兩種情況下,「NewVariableInsideTheClass」之前都不存在,我在課堂內首次創建該變量。因此,該方法應該首先創建一個不存在的實例(我認爲這是一個類中的變量的名稱),然後將其值設置爲「測試」,但我真的找不到/如何搜索這樣做...

這將是正確的問題,我需要什麼?

非常感謝!

-----------------編輯---------------------

好的,如此我想要做的是得到相同的結果時做:

SC.NewVariableInsideTheClass.add("test") 

,做的時候:

SC.NewVariableInsideTheClass.add("test") 

但是它們都必須在類外進行,以「NewVariableInsideTheClass」正在使用的第一次!這裏的目標是將類用作變量存儲,例如當第一次使用變量時會發生什麼,如果它已經存在(以SC.NewVariableInsideTheClass的形式),我將能夠以不同的方式使用它。 希望這個更具體一些...

SECOND EDIT;原因爲什麼-------------------------

哇你的回答質量和細節印象深刻,我非常感謝!像你一樣知道我爲什麼要這樣做的原因:我正在創建一個簡單的Python腳本IDE(現在主要是用於學習Python,有用的話)。所以代碼的基礎是它會一路創建新的變量。由於程序也會創建函數,因此創建和處理變量的第一個解決方案是將創建的程序中的所有變量全局化,並在每個新函數中再次調用它們。那麼代碼是醜陋的,所以我決定學習和使用一個類,但是因爲變量在每個程序中都有所不同,所以我想要標準化函數創建(即不需要知道它的第一個函數是否需要初始化變量,或者它們已經存在),方法是: - 在一個名爲變量的列表中存儲一個新變量(即使該列表不存在,並且可以輕鬆訪問該變量的名稱) - 能夠擴展前一個變量的新值作爲列表中的新項目 - 能夠檢索這些值 所有未使用全局變量的情況下,我遇到了此解決方案。其實我修改了你的代碼,現在我正在使用你的代碼,而不是命名爲「add」,我將其命名爲「append」,所以我可以自由地做:

SC.NewVar.append('This is new value') (這是新值)

第一次,它將被創建(因爲它不存在),但第二次新值被追加,因此,我將能夠稱它爲/玩它或在自動生成的代碼:)

+0

您是否正在嘗試完成動態變量的創建?這個問題的目的是什麼,它非常模糊.. –

+0

你能解釋一下你爲什麼要這樣做嗎?這可能是可能的,但它打破了一些關於Python如何工作的預期。 –

+0

是的,即時通訊抱歉的模糊,但我從字面上不知道如何問它,我要去評論答案,並指定更多 –

回答

4

免責聲明:我不知道你爲什麼要這麼做。如果要動態地創建使用屬性setattr應該足夠了:

SC = SimpleClass() 
setattr(SC, 'your_new_attribute_name', 'test') 

無論如何,有得到你想要使用什麼樣的輔助類的簡單方法:

In [1]: class SimpleClass: 
    ...:  def __getattr__(self, attr): 
    ...:   return AttributeSetter(self, attr) 
    ...: class AttributeSetter: 
    ...:  def __init__(self, inst, attr): 
    ...:   self._inst = inst 
    ...:   self._attr = attr 
    ...:  def add(self, value): 
    ...:   setattr(self._inst, self._attr, value) 
    ...:   

In [2]: SC = SimpleClass() 

In [3]: SC.new_attr.add('test') 

In [4]: SC.new_attr 
Out[4]: 'test' 

關於你的評論。如果你問是否有可能寫SimpleClass使得:

'test' 調用 Sc.new_attr.add('test')電話
SC.new_attr 

回報:

SC.new_attr.add('other') 

是這樣的:

SC.new_attr 

現在返回字符串'other',那麼答案是:不,這是不可能的

這是不可能寫一個類使得下列不產生AttributeError

In [2]: SC = SimpleClass() 

In [3]: SC.new_attr.add('test') 
In [4]: SC.new_attr #this returns a string, not a user-defined class 
'test' 

In [5]: SC.new_attr.add('new value') 
--------------------------------------------------------------------------- 
AttributeError       Traceback (most recent call last) 
<ipython-input-5-f218074b7a68> in <module>() 
----> 1 SC.new_attr.add('new value') 

AttributeError: 'str' object has no attribute 'add' 

你問這個幹什麼?好吧,讓我們來看看有什麼解釋實際上確實

In [5]: import dis 
    ...: dis.dis(lambda: SC.new_attr.add('some string')) 
    ...: 
    2   0 LOAD_GLOBAL    0 (SC) 
       3 LOAD_ATTR    1 (new_attr) 
       6 LOAD_ATTR    2 (add) 
       9 LOAD_CONST    1 ('some string') 
      12 CALL_FUNCTION   1 (1 positional, 0 keyword pair) 
      15 RETURN_VALUE 

dis模塊讓我們來看看該解釋正在執行的字節碼。 注意如何有,不同LOAD_ATTR字節碼。 正如您所看到的,解釋器首先獲得new_attr屬性和之後的,作爲完全獨立的操作,它將檢索add屬性。

現在,類SC只能修改第一個屬性訪問的行爲(即訪問new_attr)。它有沒有辦法知道下一個字節碼將訪問add,因此唯一明智的做法是返回設置的字符串。

以下屬性訪問add完成取值。這意味着解釋器尋找字符串的add屬性,這顯然不存在。

避免這種AttributeError將返回一個具有add方法的對象的唯一方法,但是這也意味着這樣做:

In [6]: SC.new_attr 
Out[6]: 'test' 

失敗因爲而不是返回字符串"test"我們會返回一個不同的對象。

解決的辦法是返回一個具有add方法,也是一個value屬性的對象,這樣我們就得到這樣的:

In [12]: SC.new_attr 
Out[12]: <__main__.TheClass at 0x7fac44727a90> 

In [13]: SC.new_attr.value 
Out[13]: 'test' 

In [14]: SC.new_attr.add('other') 

In [15]: SC.new_attr.value 
Out[15]: 'other' 

不同的解決辦法是寫這個類這樣它的行爲像一個字符串(我們甚至可以子類str不這樣做!子類化內置的是從未做正確的事情,如果你這樣做不知道你確切的後果有問題,他們會難以發現和解決),但這意味着代碼將變得更加複雜,必須實現全部字符串支持的操作(這意味着實現大約80-90-100個方法!)

+0

非常感謝。我還有一個問題,有沒有辦法,如果你做兩次「SC.new_attr.add('test')」它只會重新設置new_attr值'test',而不是嘗試將值設置爲海峽? –

+0

@Iwantbadges更新。簡短的回答*你不能*做到你想要的。另外,我想強調一下:*你想要做的事情真的很糟糕**代碼實踐*。可以嘗試這個東西來知道你可以做什麼,不能在python中做什麼,但是*不要在任何項目/產品代碼中使用它*! – Bakuriu

+0

解釋爲什麼我需要編輯問題 –

0

允許聲明使用它從任何其他函數的方法的類ABC添加

class ABC(object): 
    def add(self, var): 
     self.new_var = var 

現在增加爲實例方法,從而實現您所設置的做出來的是一個實例方法內聲明的實例變量。

a = ABC() 
# Make an instance 
a.add('test') 
# created a new variable inside instance 
a.new_var 
'test' 
+0

好吧,非常感謝你,這是一個開始,但我忘記解釋得很好:我希望「new_var」是一個動態名稱,不是在類中聲明的,而是在其外部聲明的,並且直接通過調用它, –