我可以使用 python 元类来跟踪单独文件中的子类吗?
Posted
技术标签:
【中文标题】我可以使用 python 元类来跟踪单独文件中的子类吗?【英文标题】:Can I use a python metaclass to keep track of subclasses in separate files? 【发布时间】:2015-01-06 03:35:24 【问题描述】:我是社区的新手。在我的 Django 项目中,我有一个名为“social”的模块,其中有几个文件,如 facebook.py 和 twitter.py,每个文件的类都是“SocialProvider”的子类
例子
class Facebook(SocialProvider):
在我的社交模块中还有一个名为“helper.py”的文件,其中包含一个 SocialProviderHelper,我想跟踪所有 SocialProvider 子类,并为它们生成不同的列表和标识符。例如.. SocialProviderHelper 可以“找到” Facebook 和 Twitter,并将它们添加到各种列表中,例如 cool_providers = [] popular_providers = [] old_providers 等。目标是制作一个通用的 SocialProviderHelper,其他领域的代码可以导入和使用......例如......在一个视图中我可能想要获取所有“popular_providers”名称......所以我会导入 SocialProviderHelper.. 并执行类似
的操作helper = SocialProviderHelper()
helper.getOldProviders()
在我的 SocialProviderHelper 中,我有:
class SocialProviderHelper(object):
_providers = SocialProvider.__subclasses__()
但是 子类() 似乎返回一个空列表,因为“提供者”是在尚未导入的其他文件中定义的,并且 subclasses() 仅在它们“活动”时维护对该类的弱引用。
有没有办法解决这个问题?
**最终目标是能够在任何地方创建另一个 SocialProvider 子类,只需这样做......
import SocialProvider
class NewSocialNetwork(SocialProvider)
...让 SocialProviderHelper 知道它的存在。**
我尝试使用保留子类注册表的元类来实现“subclasses(),但类似的问题仍然存在。
【问题讨论】:
【参考方案1】:这可以通过装饰器来完成:
from SocialProvider import SocialProvider
@SocialProvider.Register
class NewSocialProvider( SocialProvider ):
pass
我假设SocialProvider
是您编写的超类。如果是这样,在您的超类文件中,Register
帮助器可以定义为类方法:
class SocialProvider:
subclasses = []
@classmethod
def Register( cls, subcl ):
cls.subclasses.append( subcl )
return subcl
如果不是,那么您仍然可以在某个地方定义一个函数,用作装饰器,但它和它附加到的列表必须在其他地方定义,与SocialProvider
类分开。您提到了尚未导入文件的问题。您无法检测尚未定义的类,因此您必须确保已导入具有子类定义的文件 (例如,通过 import facebook
等语句在模块的___init__.py
文件中)。
【讨论】:
我没有足够的声誉来支持您的答案,但非常感谢!我会试试这个! 很高兴听到它有用。如果事实证明可以解决您的问题,您可以通过单击至少与赞成票一样好的勾选标记来“接受”它。以上是关于我可以使用 python 元类来跟踪单独文件中的子类吗?的主要内容,如果未能解决你的问题,请参考以下文章