【发布时间】:2021-10-24 01:06:03
【问题描述】:
我正在创建一个装饰器,用于创建特定于模块的使用类(仅接受特定模块中的类的实例化),并且我正在尝试更改该类的 __init__ 方法中的代码。我尝试将一些编译后的代码添加到对象的 __init__ 方法的 __code__ 属性中,如下所示:
klass.__init__.__code__ += hook
我的完整装饰器:
def ModuleSpecificUse(klass=None, module=__name__):
def decorator(cls):
hook = compile("""\nif __name__ != module:
raise ValueError("cannot use object")""", __name__ + ".py", "exec")
klass.__init__.__code__ += hook
return klass
return decorator
然后我尝试像这样使用ModuleSpecificUse 装饰器:
@ModuleSpecificUse(module="foo")
class C:
pass
得到了这个错误:
Traceback (most recent call last):
File "C:/.../test.py", line 13, in <module>
class C:
File "C:/.../test.py", line 5, in decorator
klass.__init__.__code__ += hook
AttributeError: 'method-wrapper' object has no attribute '__code__'
ModuleSpecificUse 装饰器的理想用途是首先创建一个由ModuleSpecificUse 装饰的类:
@ModuleSpecificUse(module="some_module")
class C:
<code>
如果模块不是some_module,则应该引发异常:
ValueError: cannot use object
【问题讨论】:
-
ModuleSpecificUse的典型用法是什么样的?几乎可以肯定,有比尝试修改函数的__code__属性更好的方法。 -
我认为可以装饰方法来做你想做的事(尽管不是以这种方式)。请提供minimal reproducible example 以说明如果它有效,将如何使用它 - 以及其他人可以用作测试用例的东西。
-
更具体地说:您希望通过限制可以实例化类的模块来避免什么错误?
-
我认为@chepner 的意思是这听起来很像XY Problem。
-
如果
C的定义首先会引发错误,为什么还要在some_module.py中定义它?如果您确实 允许定义类而不是引发错误,会发生什么? (无论如何,真正想要颠覆您的支票的人只会将其他参数传递给ModuleSpecificUse。)
标签: python python-3.x methods decorator python-decorators