【发布时间】:2021-06-08 10:25:02
【问题描述】:
让我们来一个具有这种文件夹结构的项目:
> eval
> a
> __init__.py
> a.py
> b
> __init__.py
> b.py
__init__.py
__init__.py
m.py
a文件夹中__init__.py的内容:
from eval.a.a import A
a.py的内容:
class A:
def __init__(self) -> None:
pass
def __repr__(self) -> str:
return "Class A"
def __str__(self) -> str:
return "Class A"
def exec(self):
a = eval('A()');
print(a)
b = eval('B()');
print(b)
b文件夹中__init__.py的内容:
from eval.b.b import B
b.py的内容:
class B:
def __init__(self) -> None:
pass
def __repr__(self) -> str:
return "Class B"
def __str__(self) -> str:
return "Class B "
def exec(self):
a = eval('A()');
print(a)
b = eval('B()');
print(b)
eval文件夹中__init__.py的内容:
from eval.a.a import A
from eval.b.b import B
__init__.py eval 文件夹外没有任何内容。
m.py的内容:
from eval.a import A
from eval.b import B
a = eval('A()');
print(a)
b = eval('B()');
print(b)
到目前为止,它可以工作,创建我的 A() 和 B() 对象,打印:
Class A
Class B
但如果我将 m.py 更改为:
from eval.a import A
from eval.b import B
a = eval('A()');
print(a)
b = eval('B()');
print(b)
print('Running A.exec() now:')
a.exec()
print('Running B.exec() now:')
b.exec()
然后我会得到:
Class A
Class B
Running A.exec() now:
Class A
Traceback (most recent call last):
File "c:\dev\test\python\teste_eval\m.py", line 19, in <module>
a.exec()
File "c:\dev\test\python\teste_eval\eval\a\a.py", line 15, in exec
b = eval('B()');
File "<string>", line 1, in <module>
NameError: name 'B' is not defined
那么问题是:
-
如果在我创建的文件中我已经导入了 A 类和 B 类,为什么我的 A.exec() 不能使用我的 B 类?
-
如何解决?什么意味着让我系统中的任何类都可以由任何类创建,即使是在一个单独的模块中(如本例中的“eval”模块)?
-
有没有比使用 eval 函数动态创建这些类的最好方法?
感谢您的支持。
【问题讨论】:
-
仅仅因为名称
B存在于一些 模块中并不意味着它存在于无处不在。 Python 没有全局命名空间,每个模块都有自己的命名空间。 -
动态是什么意思?
eval在您的代码中没有任何用处,因此很难理解您想要做什么,而您只需删除 eval 并将源代码直接放入您的.py文件中,而不是作为传递的字符串到eval -
另请注意,您创建的不是类,而是这些类的实例
-
“如果在我创建的文件中我已经导入了类 A 和 B,为什么我的类 B 对我的 A.exec() 不可用?”因为这无关紧要,所以名称必须在使用时可用。您似乎假设作用域是动态工作的,但它不是,python 使用词法作用域,而不是动态作用域。
-
那你就有点麻烦了,因为 Python 在这里的行为与其他语言有些不同。每个模块都需要显式导入它需要访问的名称。没有全局共享的命名空间。
标签: python class dynamic eval creation