我试图通过装饰我的Django(ORM)模型(类定义)来自动编码100个数据库表模型,从而从文件名中派生出它们的类名。但我觉得我的“装饰深度”太浅了。我需要在我的__call__
方法中使用函数def
或类定义吗?像这样简单的事情就做不到吗?在
# decorators.py
import os
from inspect import get_module
class prefix_model_name_with_filename(object):
'Decorator to prefix the class __name__ with the *.pyc file name'
def __init__(self, sep=None):
self.sep = sep or ''
def __call__(self, cls):
model_name = os.path.basename(getmodule(cls).__file__).split('.')[0]
setattr(cls, '__name__', model_name + self.sep + getattr(cls, '__name__'))
return cls
decorator的示例用法
^{pr2}$模型不存在于具有新名称的模块定义中,并且我不能使用它而不在decorator类(而不是model类)中查找属性!在
>>> from sec_mirror.models import ShipMeth
>>> ShipMeth.__name__
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/home/Hobson/.virtualenvs/dev/lib/python2.7/site-packages/django/core/management/commands/shell.pyc in <module>()
----> 1 ShipMeth.__name__
AttributeError: 'prefix_model_name_with_filename' object has no attribute '__name__'
我需要装点模块吗?在
您使用类本身作为装饰器,因此只调用它的
__init__
。你的__call__
永远不会被调用。在请改用实例:
关于您更新的问题:decorator不能更改用于引用封闭命名空间中对象的实际名称。(您可以通过将一个新名称粘贴到特定的名称空间中来强制执行此操作,但这取决于您确保将名称放入其中的名称空间是最初定义对象的名称空间。)decorator语法:
^{pr2}$相当于
注意最后一行是
Foo =
,因为原始类是用class Foo
定义的。你不能改变这一点。装饰后的对象总是重新指定为它原来的名称。在有一些老掉牙的方法来解决这个问题。您可以让decorator向全局名称空间写入一个新名称,甚至可以查看修饰对象的
__module__
属性并向该名称空间写入一个新名称。然而,这并不是decorator的真正目的,它会使代码变得混乱。decorator用于修改/包装对象,而不是修改从中访问这些对象的命名空间。在也许这就是元类的工作:
上一个示例只创建名称已更改的新类,但如果您希望模块反映您对此所需的更改(请注意,我的python脚本名为untitled0.py):
^{pr2}$输出:
相关问题 更多 >
编程相关推荐