动态创建类时Python错误



让我们以这个文件夹结构的项目为例:

> eval
> a
> __init__.py
> a.py
> b
> __init__.py
> b.py
__init__.py
__init__.py
m.py

__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)

__init__.py含量在b文件夹:

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)
__init__.py内容在eval文件夹:
from eval.a.a import A
from eval.b.b import B

__init__.pyeval文件夹里面什么也没有

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:devtestpythonteste_evalm.py", line 19, in <module>
a.exec()
File "c:devtestpythonteste_evalevalaa.py", line 15, in exec
b = eval('B()');
File "<string>", line 1, in <module>
NameError: name 'B' is not defined

那么问题是:

  1. 为什么我的类B不可用于我的A.exec()如果在文件中,我创建了类,我导入了类A和B?

  2. 如何修复?什么意味着我的系统中的任何类都可以被任何类创建,甚至在一个单独的模块中(比如这个例子中的'eval'模块)?

  3. 有一个最好的方法来创建这些类动态比使用eval函数?

感谢您的支持。

我刚刚找到了一种方法来加载所有模块。

这是一个可能的解决方案:

import sys
def get_user_modules() -> list:
ret = []
sm = sys.modules
for k in sm.keys():
if (k[0] != '_'):
if (not k.startswith('encodings.')):
if (not (k in ['sys', 'builtins', 'nt', 'marshal', 'winreg', 'time', 'zipimport', 'codecs', 
'encodings', 'abc', 'io', 'stat', 'genericpath', 'ntpath', 'os', 'site', 'os.path'])):
ret.append(k)
return ret

这段代码将返回:

['eval.a.a', 'eval.a', 'eval.b.b', 'eval.b', 'eval']

示例中使用的系统结构。

我认为最终的解决方案应该基于加载的模块列表。

感谢所有试图帮助我的人。

更新:另一种可能是从起始点到最后一个文件夹遍历文件系统,如下所示:

def get_all_modules() -> list:
r = os.path.dirname(sys.argv[0])
t = len(r)
l = []
for root, dirs, files in os.walk(r):
s = root[t:].replace('\', '.')
for f in files:
if (f.endswith('.py') and (f[0:2] != '__')):
fn = f[:-3]
if (s != ''):
fn = s[1:] + '.' + fn
l.append(fn)
return l

然后,我可以使用:

def import_all_modules() -> str:
um = get_all_modules()
s  = ''
for k in um:
if (k != __name__):
s = s + f'from {k} import *n'
return s

为了得到我需要导入和执行的所有内容:

exec(import_all_modules())

因此,我将动态导入应用程序中定义的所有类。

相关内容

  • 没有找到相关文章

最新更新