【发布时间】:2012-08-20 21:17:46
【问题描述】:
在尝试从具有元类的类继承时,我在 Python 中遇到了一些非常奇怪的问题。我有这个:
class NotifierMetaclass(type):
def __new__(cls, name, bases, dct):
attrs = ((name, value) for name, value in dct.items()
if not name.startswith('__'))
def wrap_method(meth):
return instance_wrapper()(meth) # instance_wrapper is a decorator of my own
def is_callable(value):
return hasattr(value, '__call__')
decorated_meth = dict(
(name, value) if not is_callable(value)
else (name, wrap_method(value))
for name, value in attrs
)
return super(NotifierMetaclass, cls).__new__(
cls, name, bases, decorated_meth
)
class Notifier(object):
def __init__(self, instance):
self._i = instance
__metaclass__ = NotifierMetaclass
然后,在 notifiers.py 中:
from helpers import Notifier
class CommentNotifier(Notifier):
def __notification__(self, notification):
return '%s has commented on your board' % self.sender
def __notify__(self):
receivers = self.retrieve_users()
notif_type = self.__notificationtype__()
for user in receivers:
Notification.objects.create(
object_id=self.id,
receiver=user,
sender_id=self.sender_id,
type=notif_type
)
但是,当我尝试导入 CommentNotifier 时,它会返回 Notifier。在外壳中:
$ python
Python 2.7.3 (default, Apr 20 2012, 22:44:07)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from logic.notifiers import CommentNotifier
>>> CommentNotifier
<class 'helpers.CommentNotifier'>
事实上,这(至少我是这么认为的)实际上与我一周前遇到的一些Django models 的问题相同。起初我认为这与 Django 的工作方式有关,但现在我怀疑它更像是元类和继承的 Python“问题”。
这是一个已知问题还是我只是做错了什么?希望你能帮助我。
编辑:我忘了提到我将此“错误”归因于元类,因为如果我不给通知程序一个元类,它会按预期工作。
【问题讨论】:
-
您的示例对我来说是正确的。你没有在“东西”部分省略一些重要的东西吗?请提供一个实际表现出您所指行为的示例。
-
刚刚编辑了真实案例的代码
-
我得到
<class 'helpers.CommentNotifier'>(仅使用两个文件,helpers.py和notifiers.py),如果我把它放在一个包中,则得到<class 'logic.helpers.CommentNotifier'>。尝试进一步减少它,并在不同的地方粘贴一些打印语句,以排除您没有导入您认为的版本的可能性。 -
我也得到了@DSM 看到的行为。我相信您的问题不在于它导入了错误的类,而是它给了它错误的名称(或者至少是错误的
__module__)。 This question 提到了同样的问题,但没有答案。似乎__module__被错误地设置为元类的模块而不是类的模块。我仍在试图弄清楚。 . .
标签: python inheritance metaclass