[英]python3: convert string to type
I have a set of classes A
, B
, C
in a "front end" package p1
. 我在“前端”包
p1
有一组类A
, B
, C
。 They all inherit from p1.X
. 它们都继承自
p1.X
I have another set of classes A
, B
, C
in a "back end" package p2
. 我在“后端”包
p2
有另一组类A
, B
, C
。 They all inherit from p2.Y
. 它们都继承自
p2.Y
In p1.X
, I set one backend, so that p1.A
uses p2.A
as backend, p1.B
uses p2.B
, etc. This mapping is done based on the class name in an inherited method. 在
p1.X
,我设置了一个后端,以便p1.A
使用p2.A
作为后端, p1.B
使用p2.B
等。此映射是基于继承方法中的类名完成的。
Now, I suceed to have, for example, backend = "p2.A"
(string), but when I try to eval this, python doesn't knows about p2
, even if this is imported earlier. 现在,我想拥有例如
backend = "p2.A"
(字符串),但是当我尝试对此求值时,python不知道p2
,即使它是较早导入的。
What did I do wrong? 我做错了什么? Should I import inside the eval?
我应该在评估中导入吗? Should like spaghetti code... Do you have a better idea?
应该像意大利面条代码...您有更好的主意吗?
Thanks. 谢谢。
PS: I currently have something like this in the "parent" p1.X
class, which is awful, but good to clarify what I want: PS:我目前在“父级”
p1.X
类中有类似的内容,这很糟糕,但是很好地阐明了我想要的内容:
def getBackendClass(self):
myClass = ... # (class without package name)
if myClass == "A":
return p2.A
elif myClass == "B":
return p2.B
...
Little hacky solution, but should work, and is not hardcoded. 小小的hacky解决方案,但是应该可以使用,并且没有经过硬编码。
p2.py: 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)
Perhaps you mean something like this? 也许您的意思是这样的? Whenever the
backend_class
attribute is fetched it will call it's __get__
method and return the result of that call. 每当获取
backend_class
属性时,它将调用它的__get__
方法并返回该调用的结果。 The BackendClassFetcher
is known as a non-data descriptor. BackendClassFetcher
被称为非数据描述符。
package1/m1.py 包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)
package1/m2.py 包1 / m2.py
class Parent: pass
class A(Parent): pass
class B(Parent): pass
class C(Parent): pass
You can use import_module
. 您可以使用
import_module
。 Documentation 文献资料
sample: 样品:
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)
Good luck. 祝好运。
Thanks a lot. 非常感谢。 I've made a mix of all your answers, leading the following code in the front end:
我综合了您的所有答案,在前端使用了以下代码:
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()
Comment about cython: the backend must be imported, not cimported, even if "pure cython" cdef
classes/ cpdef
methods. 关于cython的评论:即使“纯cython”
cdef
类/ cpdef
方法,也必须导入后端,而不是cimport。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.