[英]Method that applies to instance of a class in python // Apply a method to an instance of a class in python
我開始在python中創建類,我對這些術語非常困惑,所以我找不到我的問題的答案,因為我不知道如何問這些,因此這篇文章的雙重標題。 我將嘗試用以下代碼澄清我不知道如何問的問題:
我想在一個簡單的類中創建一個方法:
class SimpleClass:
add(self,Value)
#Magic goes here
SC=SimpleClass()
該方法應該等同於向類添加新變量:
SC.NewVariableInsideTheClass="test"
但通過一種方法,例如:
SC.NewVariableInsideTheClass.add("test")
在兩種情況下“NewVariableInsideTheClass”之前都不存在,我在類中第一次創建該變量。
所以該方法應首先創建非現有實例(我認為這是類中變量的名稱),然后將其值設置為“test”,但我真的找不到/搜索如何做到這一點。 。
哪個是我需要的正確問題?
非常感謝你!
-----------------編輯---------------------
好的,所以我想做的是在做的時候得到相同的結果:
SC.NewVariableInsideTheClass.add("test")
在做的時候:
SC.NewVariableInsideTheClass.add("test")
但兩者都必須在課外完成,“NewVariableInsideTheClass”是第一次使用! 這里的目標是使用類作為變量存儲,例如當第一次使用變量時會發生某些事情,如果它已經存在(以SC.NewVariableInsideTheClass的形式),我將能夠以不同的方式使用它。 希望現在更具體一點......
第二次編輯; 原因 - - - - - - - - - - - - -
哇我對你答案的質量和細節印象深刻,我非常感激! 我想知道我想要這個的原因:我正在創建一個簡單的python腳本IDE(現在主要用於學習python,nhot有用)。 因此,代碼的基礎是它在此過程中創建新的變量。 由於程序也將創建函數,我的第一個創建和處理變量的解決方案是在創建的程序全局變量中創建所有變量,並在每個新函數中再次調用它們。 好吧,代碼很丑,所以我決定學習並使用一個類,但由於變量在每個程序中都不同,我想要標准化函數創建(即不需要知道它是否是第一個函數,如果它需要初始化任何變量,或者如果它們已經存在),能夠: - 在名為變量的列表中存儲一個新變量,即使它不存在,也有一個我可以輕松訪問的名稱-Be能夠擴展之前的變量變量將新值作為列表中的新項 - 能夠檢索這些值所有不使用全局變量,我遇到了這個解決方案。 實際上我修改了你的代碼,現在我正在使用你的代碼,但不是命名“添加”我命名為“追加”,所以我可以自由地做:
SC.NewVar.append('這是新值')SC.NewVar.append('這是新值')
第一次,它將被創建(因為它不存在),但第二次附加新值,因此,我將能夠調用它/播放它或從自動生成的任何其他函數中使用它 - 代碼:)
免責聲明 :我不知道你為什么要這樣做。 如果要使用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
,那么:
SC.new_attr
返回字符串 'test'
並 在調用Sc.new_attr.add('test')
后調用:
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個方法! )
讓我們使用方法add聲明一個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'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.