2017-08-27 49 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一起使用,但可能会违反​​的各种语言不变量。这样做远非安全。