我试图向自己证明我可以重新定义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中更改内置函数的行为?或者我只是做错了?
答案 0 :(得分:0)
您遇到的特定错误是因为您已声明class object(type)
。这不是你声明你希望你的类成为一个类型的方式;所有类都是类型(除非你使用的是Python 2并且你创建了一个经典类)。
您已声明您希望您的类成为type
的子类,因此您的类的所有实例都将是类型。 return super(object, self).__new__(...)
正在调用type.__new__
,但不会传递您传递的内容。
除了上述问题,你还有更多的问题,有些是肤浅的,有些是根本性的。最根本的是定义自己的名为object
的类不会对内置object
类型执行任何操作。虽然技术上可以使用object
来固定内置的ctypes
,但可能违反ctypes
的各种语言不变量。这样做远非安全。