Python:我可以覆盖对象中的__getattr__(内置)吗?

时间:2017-08-27 18:17:45

标签: python metaprogramming

我试图向自己证明我可以重新定义Python语言的语法。基本上,元编程的一个方面。但我正在努力覆盖内置object类的行为。

我尝试更改当对象没有特定属性时引发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()事件爆发期间的爆发:

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)

错误消息对我来说似乎不对。我肯定在__new__中至少传递了一个参数:

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

最初我根本没有传递那个论点,因为无论如何都应该在*args内传递这个类。我已经将print语句添加到__new__方法中,发现没有任何内容传递给它。

是否真的无法在Python中更改内置函数的行为?或者我只是做错了?

1 个答案:

答案 0 :(得分:0)

您遇到的特定错误是因为您已声明class object(type)。这不是你声明你希望你的类成为一个类型的方式;所有类都是类型(除非你使用的是Python 2并且你创建了一个经典类)。

您已声明您希望您的类成为type子类,因此您的类的所有实例都将是类型。 return super(object, self).__new__(...)正在调用type.__new__,但不会传递您传递的内容。

除了上述问题,你还有更多的问题,有些是肤浅的,有些是根本性的。最根本的是定义自己的名为object的类不会对内置object类型执行任何操作。虽然技术上可以使用object来固定内置的ctypes,但可能违反ctypes的各种语言不变量。这样做远非安全。