gpt4 book ai didi

python - 在不知道存在多少文件的情况下加载 py 文件并在目录的 for 循环中对类执行某些操作?

转载 作者:太空宇宙 更新时间:2023-11-04 04:02:55 25 4
gpt4 key购买 nike

我正在尝试使用一个目录来保存不断增长的框架列表,当我的 MAIN.py 文件被执行时,我希望代码将每个框架加载到 Tkinter 笔记本小部件中。

我可以通过从我的 MAIN 文件夹的子目录中导入每个文件来手动执行此操作,但是我试图以实用的方式加载它们,而不必知道每个文件名,也不必自己导入它们。

我已经取得了一些进展,但我在实际加载文件中的类时遇到了困难。我可以获得所有文件的列表,我相信我正在导入它们,我只是无法加载它们,因为它一直告诉我模块不存在。

我一定是误解了这里的某些东西,因为我无法弄清楚如何从导入的文件中正确调用类。

错误:

C:\Users\USER\PycharmProjects\TEST\venv\Scripts\python.exe C:/Users/USER/PycharmProjects/TEST/MAIN/MAIN.py
# This below list is a result of my print statement to see if I got all the file names.
['TaskFrame', 'TestFrame1', 'TestFrame2', 'TestFrame3']
Traceback (most recent call last):
File "C:/Users/MCDOMI3/PycharmProjects/TEST/MAIN/MAIN.py", line 46, in <module>
ScriptManager().mainloop()
File "C:/Users/MCDOMI3/PycharmProjects/TEST/MAIN/MAIN.py", line 39, in __init__
self.add_frame_to_book(foo.tab_title)
AttributeError: module 'ScriptFrames.TaskFrame' has no attribute 'tab_title'

主要代码:

import tkinter as tk
import tkinter.ttk as ttk
from os.path import dirname, basename, isfile, join
import glob
import importlib.util

modules = glob.glob(join(dirname('.\ScriptFrames\\'), "*.py"))
__all__ = [basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]
print(__all__)


class ScriptManager(tk.Tk):

def __init__(self):
super().__init__()
self.book = ttk.Notebook(self)
self.book.grid(row=0, column=0, sticky='nsew')
for fn in __all__:
spec = importlib.util.spec_from_file_location('ScriptFrames.{}'.format(fn),
'.\ScriptFrames\\{}.py'.format(fn))
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
# Here is my problem I do not know if I am attempting to get the class
# attribute correctly here. I am sure that I am calling this wrong.
self.add_frame_to_book(foo.tab_title)

def add_frame_to_book(self, fname):
self.book.add(fname, text='test')


if __name__ == '__main__':
ScriptManager().mainloop()

每个测试文件都是一个简单的 tkinter 框架。

测试框架代码:

import tkinter as tk
import tkinter.ttk as ttk


class TabFrame(ttk.Frame):

def __init__(self):
super().__init__()
self.tab_title = 'Test Frame 1'
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
tk.Label(self, text='test').grid(row=0, column=0, sticky='nsew')

如果对我有帮助,这是我的文件结构:

enter image description here

最佳答案

您正在尝试访问模块的 tab_title,而不是从其中的 (Frame) 类。

加载模块后,使用 [Python 3.Docs]: Built-in Functions 获取其属性:

  • 获取模块属性名(使用dir)
    • 对于每个名称,获取相应的属性(使用getattr)
    • 测试属性是否为 ttk.Frame(因为模块还有其他属性)
      • 如果是框架类,实例化它以访问tab_title,否则直接丢弃

示例:

# ...
# The rest of your code

spec.loader.exec_module(foo)

# At this point, 'foo' module is loaded. Get its attributes
module_attrs = [getattr(foo, attr_name, None) for attr_name in dir(foo)]

# Filter out the attributes only keeping the ones that we care about
frame_classes = [attr for attr in module_attrs if isinstance(attr, (type,)) and issubclass(attr, (ttk.Frame,))]

# Then handle the module classes (it will probably be only one)
for frame_class in frame_classes:
if frame_class.__name__.startswith("Tab"): # Or any other filtering
# It would have been much more efficient to filter names when computing attr_names, but it's more consistent to be here (especially if other filtering beside name is needed)
frame_class_instance = frame_class() # Instantiate the class, as tab_title is an instance attribute
print(frame_class.__name__, frame_class_instance.tab_title)

关于python - 在不知道存在多少文件的情况下加载 py 文件并在目录的 for 循环中对类执行某些操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57876704/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com