比较Python中的类型
我正在制作一个模块动态加载的基础设施。每个模块应包含一个从同一基类继承的类 模块的结构如下所示:比较Python中的类型,python,class,vendor,Python,Class,Vendor,我正在制作一个模块动态加载的基础设施。每个模块应包含一个从同一基类继承的类 模块的结构如下所示: app \- vendors \- __init__.py \- vendor_base.py \- vendor1.py \- vendor2.py ... \uuuu init\uuuuu.py: from .vendor_base import VendorBase self = sys.modules[__name__] __all__ = [] vendors = [] modu
app
\- vendors
\- __init__.py
\- vendor_base.py
\- vendor1.py
\- vendor2.py
...
\uuuu init\uuuuu.py
:
from .vendor_base import VendorBase
self = sys.modules[__name__]
__all__ = []
vendors = []
modules = [ f
for f in glob.glob(join(dirname(__file__), "*.py"))
if isfile(f) and not f.endswith('__init__.py')
]
for module in modules:
with open(module, 'rb') as fp:
module_name = splitext(basename(module))[0]
ma = imp.load_module(
'app.vendors.' + module_name,
fp, basename(module), ('.py', 'r', imp.PY_SOURCE))
classes = { c for c in ma.__dict__.items()
if isinstance(c[1], type) and issubclass(c[1], VendorBase) }
for class_pair in classes:
setattr(self, class_pair[0], class_pair[1])
if class_pair[0] not in __all__:
__all__.append(class_pair[0])
if issubclass(class_pair[1], VendorBase):
vendors.append(class_pair[1])
from abc import ABCMeta, abstractmethod
class VendorBase(metaclass=ABCMeta):
@classmethod
def __subclasshook__(cls, subclass):
return subclass is not cls and cls in subclass.__mro__
@abstractmethod
def post_purchase_order(self, purchase_order):
pass
from . import VendorBase
class Vendor1(VendorBase):
def post_purchase_order(self, purchase_order):
pass
from . import VendorBase
class Vendor2(VendorBase):
def post_purchase_order(self, purchase_order):
pass
vendor_base.py
:
from .vendor_base import VendorBase
self = sys.modules[__name__]
__all__ = []
vendors = []
modules = [ f
for f in glob.glob(join(dirname(__file__), "*.py"))
if isfile(f) and not f.endswith('__init__.py')
]
for module in modules:
with open(module, 'rb') as fp:
module_name = splitext(basename(module))[0]
ma = imp.load_module(
'app.vendors.' + module_name,
fp, basename(module), ('.py', 'r', imp.PY_SOURCE))
classes = { c for c in ma.__dict__.items()
if isinstance(c[1], type) and issubclass(c[1], VendorBase) }
for class_pair in classes:
setattr(self, class_pair[0], class_pair[1])
if class_pair[0] not in __all__:
__all__.append(class_pair[0])
if issubclass(class_pair[1], VendorBase):
vendors.append(class_pair[1])
from abc import ABCMeta, abstractmethod
class VendorBase(metaclass=ABCMeta):
@classmethod
def __subclasshook__(cls, subclass):
return subclass is not cls and cls in subclass.__mro__
@abstractmethod
def post_purchase_order(self, purchase_order):
pass
from . import VendorBase
class Vendor1(VendorBase):
def post_purchase_order(self, purchase_order):
pass
from . import VendorBase
class Vendor2(VendorBase):
def post_purchase_order(self, purchase_order):
pass
vendor1.py
:
from .vendor_base import VendorBase
self = sys.modules[__name__]
__all__ = []
vendors = []
modules = [ f
for f in glob.glob(join(dirname(__file__), "*.py"))
if isfile(f) and not f.endswith('__init__.py')
]
for module in modules:
with open(module, 'rb') as fp:
module_name = splitext(basename(module))[0]
ma = imp.load_module(
'app.vendors.' + module_name,
fp, basename(module), ('.py', 'r', imp.PY_SOURCE))
classes = { c for c in ma.__dict__.items()
if isinstance(c[1], type) and issubclass(c[1], VendorBase) }
for class_pair in classes:
setattr(self, class_pair[0], class_pair[1])
if class_pair[0] not in __all__:
__all__.append(class_pair[0])
if issubclass(class_pair[1], VendorBase):
vendors.append(class_pair[1])
from abc import ABCMeta, abstractmethod
class VendorBase(metaclass=ABCMeta):
@classmethod
def __subclasshook__(cls, subclass):
return subclass is not cls and cls in subclass.__mro__
@abstractmethod
def post_purchase_order(self, purchase_order):
pass
from . import VendorBase
class Vendor1(VendorBase):
def post_purchase_order(self, purchase_order):
pass
from . import VendorBase
class Vendor2(VendorBase):
def post_purchase_order(self, purchase_order):
pass
vendor2.py
:
from .vendor_base import VendorBase
self = sys.modules[__name__]
__all__ = []
vendors = []
modules = [ f
for f in glob.glob(join(dirname(__file__), "*.py"))
if isfile(f) and not f.endswith('__init__.py')
]
for module in modules:
with open(module, 'rb') as fp:
module_name = splitext(basename(module))[0]
ma = imp.load_module(
'app.vendors.' + module_name,
fp, basename(module), ('.py', 'r', imp.PY_SOURCE))
classes = { c for c in ma.__dict__.items()
if isinstance(c[1], type) and issubclass(c[1], VendorBase) }
for class_pair in classes:
setattr(self, class_pair[0], class_pair[1])
if class_pair[0] not in __all__:
__all__.append(class_pair[0])
if issubclass(class_pair[1], VendorBase):
vendors.append(class_pair[1])
from abc import ABCMeta, abstractmethod
class VendorBase(metaclass=ABCMeta):
@classmethod
def __subclasshook__(cls, subclass):
return subclass is not cls and cls in subclass.__mro__
@abstractmethod
def post_purchase_order(self, purchase_order):
pass
from . import VendorBase
class Vendor1(VendorBase):
def post_purchase_order(self, purchase_order):
pass
from . import VendorBase
class Vendor2(VendorBase):
def post_purchase_order(self, purchase_order):
pass
因此,我希望类Vendor1和Vendor2能够加载并在模块app.vendors(在\uuuu all\uuuu
和vendors
中)中可用。但是,它们没有加载。我已经检查了VendorBase.\uuu子类hook\uuuu()
中的类的比较没有按预期工作
当我运行issubclass(VendorBase,Vendor1)
时,我得到False
。此外,即使在调试器VendorBase.\uuuu子类hook\uuuu(cls,子类)
中,其中:
cls
'app.vendors.vendor\u base.VendorBase'>
子类
'app.vendors.vendor\u base.VendorBase'>
我检查cls是子类
我仍然得到False
。
我认为它可能与供应商类模块中不同的导入基类名称有关。所以我确保
VendorBase
是从vendors
导入的,在那里它也被使用。但是仍然有不同的类实例。您已经在使用模块imp加载,然后也使用它来查找
imp.find_模块(名称[,路径])
请发布您正在寻找的
isinstance()
的进展情况<代码>在Python中是一种身份检查1为int
返回False
您可能只想使用入口点,而不是滚动您自己的加载程序。。。Reissubclass(供应商数据库,供应商1)
。你的参数倒过来了。@Flair我相信isinstance()
适用于对象。我在比较类(不是对象)@AKX每次添加插件时不需要重新运行安装程序吗?我们的想法是,一旦文件被放到目标目录,新模块就会被加载。对不起,我不明白查找模块是如何关联的。首先,最重要的是,这是一种python方式。当你有一个测试过的代码可用时,为什么还要自己编写代码呢?我仍然不明白这和问题有什么关系。