2017-01-13 41 views
1

我知道你們大部分人都是爲那個執行而不應該使用,但是我有一些問題。'exec'不能使用私有方法Python

這裏是最小的例子,它的工作原理:

class A: 
    def __init__(self): 
     exec('self.a = self.funct()') 
    def funct(self): 
     return 1 
    def ret(self): 
     return self.a 
> obj = A() 
> obj.ret() 
1 

但是,當我這樣做:

class A: 
    def __init__(self): 
     exec('self.a = self.__funct()') 
    def __funct(self): 
     return 1 
    def ret(self): 
     return self.a 
> obj = A() 
AttributeError: 'A' has no attribute '__funct' 

有誰知道這是爲什麼不同?

+1

請注意'__'名稱是** class ** private。這與其他語言的隱私模型不同。 –

回答

3

__name的名字是class private;這些名稱在編譯時加上前綴,並帶有另一個下劃線和類名。目的是爲了防止名稱與子類中使用的名稱發生意外衝突。這些名字是而不是,意思是對外部來電者是私人的。

引述Reserved classes of identifiers section

__*
類專用名稱。如果在類定義的上下文中使用此類別中的名稱,則會重新編寫該名稱以使用損壞的表格來避免名稱與派生類的「私有」屬性之間的衝突。

和​​:

私人名稱重整:當該文本方式發生在類定義的標識符與兩個或多個開始下劃線字符,並在兩個或多個下劃線並沒有結束,它被認爲是該類的私人名稱。在爲其生成代碼之前,專用名稱會轉換爲更長的形式。該轉換將在名稱前插入類名,並刪除前導下劃線和插入的單個下劃線。例如,名爲Ham的類中出現的標識符__spam將轉換爲_Ham__spam。這種轉換獨立於使用標識符的語法上下文。

你的情況會發生什麼事是,exec()推遲編譯,編譯有效這一呼籲孤立。類的上下文消失了,所以不會發生混亂。

因此,你需要手動應用自動前綴:

exec('self.a = self._A__funct()') 

如果您正在使用Python 3,你可以使用__class__關閉normally available for the super() function訪問當前方法是定義的類名:

現在
exec('self.a = self._{0.__name__}__funct()'.format(__class__)) 

,除非你確實打算爲你的類被廣泛子類第三方代碼,應該不必擔心意外內部實施細則發生衝突,你不應該使用雙U nderscore的名字。改爲使用單下劃線名稱。

0

Python私有方法在與代碼中指定的標識符不同的標識符下「僞裝」,您可以像_classname__privateAttribute一樣訪問它們。

張貼這要具體:

class A: 
    def __init__(self): 
     exec('self.a = self._A__funct()') 
    def __funct(self): 
     print("Hello") 
    def ret(self): 
     return self.a 

obj = A() 

我把打印的回答有來檢測,如果它的工作,它做到了!