【发布时间】:2014-03-22 00:42:01
【问题描述】:
我有一个元类,它只是为我的模块上的类附加一个前缀。到目前为止一切顺利,问题是我想删除调用元类的类的定义。例如,如果类 A 以 PrefixA 为前缀,我将以我的全局变量上的两个类结束,但我只想要 PrefixA 就可以了。现在为了实现我的目标,我正在做这样的事情:
class PrefixChanger(type):
prefix = 'Prefix'
to_delete = []
def __new__(cls, clsname, bases, attrs):
new_cls = type.__new__(cls,cls.prefix+clsname,bases,attrs)
globals()[cls.prefix+clsname] = new_cls
cls.to_delete.append(clsname)
return new_cls
@classmethod
def do_clean(cls):
gl = globals()
for name in cls.to_delete:
del gl[name]
class A(object):
__metaclass__ = PrefixChanger
class B(PrefixA):
pass
PrefixChanger.do_clean()
这种方法的问题是我必须将最后一行 PrefixChanger.do_clean() 放在每个使用我的元类的模块的末尾。
那么,有什么方法可以正确地做到这一点吗?我的意思是元类(或某种黑魔法)会尽快从全局中删除不需要的类(可能就在它们的定义之后)。
我有兴趣以这种方式完成任务,但也欢迎提出使用其他方法完成任务的建议。
我的解决方案也打破了这种情况:
class B(object):
class C(object):
__metaclass__ = PrefixChanger
给解决它的人加分!
【问题讨论】:
-
这在很多层面上都是一个糟糕的主意..
-
嗯,我觉得你是对的,这很奇怪,但是……有解决办法吗?
-
@MartijnPieters Elaborate,我对这种想法可能出现的问题很感兴趣(除非您只是说使用元类只是为使用该元类的类的名称添加前缀是非常愚蠢,只有一个包含前缀为名称的类的模块会更简单)。
-
最不意外的原则。可发现性、自我记录等,在这里都被违反了。
-
@JAB:这就是我要做的;提供该前缀、提供新绑定并从全局变量中清除原始名称所必须经历的痛苦对我来说是不值得的、愚蠢的、太多的工作却没有收获,使代码库不必要地复杂化,使其更难阅读代码(
PrefixA是从哪里出现的?),使得使用代码检查工具等变得更加困难。