我在“前端”包A
中有一组类B
,C
,p1
。它们都继承自p1.X
。
我在“后端”包A
中有另一组课程B
,C
,p2
。它们都继承自p2.Y
。
在p1.X
中,我设置了一个后端,以便p1.A
使用p2.A
作为后端,p1.B
使用p2.B
等。此映射基于在继承方法中的类名。
现在,我已经取代了backend = "p2.A"
(字符串),但是当我尝试评估它时,python不知道p2
,即使这是先前导入的。 / p>
我做错了什么?我应该在eval内导入吗?应该喜欢意大利面条代码......你有更好的主意吗?
感谢。
P.S。:我目前在“父”p1.X
课程中有类似的内容,这很糟糕,但很好地澄清了我想要的内容:
def getBackendClass(self):
myClass = ... # (class without package name)
if myClass == "A":
return p2.A
elif myClass == "B":
return p2.B
...
答案 0 :(得分:1)
小hacky解决方案,但应该工作,并且不是硬编码。
p2.py:
class Y(object):
@classmethod
def fromString(cls, s):
cls_name = s.split(".")[1]
for c in cls.__subclasses__():
if c.__name__() == cls_name:
return c()
raise ValueError("%s not found in subclasses" % s)
答案 1 :(得分:1)
也许你的意思是这样的?每当提取backend_class
属性时,它将调用它的__get__
方法并返回该调用的结果。 BackendClassFetcher
被称为非数据描述符。
<强>包1 / m1.py 强>
from . import p2
class BackendClassFetcher:
def __get__(self, obj, objtype):
return getattr(p2, objtype.__name__)
class Parent:
backend_class = BackendClassFetcher()
class A(Parent): pass
class B(Parent): pass
class C(Parent): pass
for cls in [A,B,C]:
obj = cls()
print(cls, cls.backend_class, obj.backend_class)
<强>包1 / m2.py 强>
class Parent: pass
class A(Parent): pass
class B(Parent): pass
class C(Parent): pass
答案 2 :(得分:0)
您可以使用import_module
。 Documentation
样品:
from importlib import import_module
path = "p2.A"
cls_name = path.split('.')[-1]
module_path = ".".join(path.split('.')[:-1])
module = import_module(module_path)
cls = getattr(module, cls_name)
祝你好运。
答案 3 :(得分:0)
非常感谢。我已经将你所有的答案混合在一起,在前端引出了以下代码:
import backend
class Parent:
@property
def backend_class(self):
return getattr(backend, self.__class__.__name__)
class A(Parent):
pass
if __name__ == "__main__":
instance = A()
backendInstance = instance.backend_class()
关于cython的评论:后端必须导入,而不是进口,即使&#34;纯cython&#34; cdef
类/ cpdef
方法。