2017-08-27 60 views
0

我試圖向自己證明我可以重新定義Python語言的語法。基本上,元編程的一個方面。但我正在努力改寫內置object類的行爲。Python:我可以覆蓋對象中的__getattr__(內置)嗎?

我試圖改變一個對象沒有特定屬性時產生AttributeError的行爲。相反,我試圖通過在案例中返回None來強制Python表現得像JavaScript一樣。這是試圖更好地理解Python內置插件的練習,而不是真正的實際問題。

我曾經修改過它,我無法再創建對象。下面是我修改的object行爲的嘗試:

#!/usr/bin/env python 

class object(type): 
    def __new__(self, *args, **kwargs): 
     print(args) 
     return super(object, self).__new__(object, *args, **kwargs) 
    def __init__(self, *args, **kwargs): 
     self._dict = {} 
     super(object, self).__init__(*args, **kwargs) 
    def __getattribute__(self, key): 
     print('GET -> LONG METHOD') 
     if key.startswith('_'): 
      raise TypeError('Cannot modify built-ins') 
     return self._dict.get(key) 
    def __getattr__(self, key): 
     print('GET -> SHORT METHOD') 
     if key.startswith('_'): 
      raise TypeError('Cannot modify built-ins') 
     return self._dict.get(key) 
    def __setattr__(self, key, value): 
     if key.startswith('_'): 
      raise TypeError('Cannot set directly on built-ins') 
     self._dict[key] = value 

class A(object): 
    pass 

a = A() 

a.yay = 7 
print(a.yay) 
print(a.yup) # should be None 

我不完全知道什麼是__getattribute__方法,但是當我檢查object我發現它有代替__getattr__該方法,所以我已經覆蓋兩者(以防萬一)。

與代碼的問題是,a = A()東西instatiation期間炸燬:

Traceback (most recent call last): 
    File "py.py", line 34, in <module> 
    a = A() 
    File "py.py", line 12, in __new__ 
    return super(object, self).__new__(self, *args, **kwargs) 
TypeError: type.__new__() takes exactly 3 arguments (0 given) 

該錯誤消息似乎我錯了。我肯定至少使1參數__new__在:

return super(object, self).__new__(object, *args, **kwargs) 

本來我是不及格這樣的說法可言,因爲類裏面應該被*args通過反正。我已將打印語句添加到__new__方法中,並發現沒有任何內容傳遞給它。

是否真的不可能改變Python中的內置行爲?或者我只是做錯了?

+0

即使你成功了,你也只會改變從你的虛假「對象」繼承而來的新類,而你通過遮蔽原來的東西而導致問題。嘗試給它一個不同的名字。也沒有一個實際上改變了*語法*。 – jonrsharpe

回答

0

您遇到的特定錯誤是因爲您聲明瞭class object(type)。這不是你如何聲明你希望你的課是一個類型;所有的類都是類型的(除非你使用Python 2並且你創建了一個經典類)。

你已經聲明你希望你的課程是的子類type,所以你的課程的所有實例都將是類型。 return super(object, self).__new__(...)打電話給type.__new__,這並不需要你傳遞它。


除了上述問題,你還有更多的問題,一些膚淺,一些根本。最基本的是定義你自己的類object不會對內置的object類型做任何事情。雖然在技術上可以使用​​與內置的object一起使用,但可能會違反​​的各種語言不變量。這樣做遠非安全。

相關問題