【问题标题】:How to use imported from another program that has a main funciton?如何使用从另一个具有主要功能的程序导入?
【发布时间】:2019-10-01 10:25:00
【问题描述】:

我正在尝试更好地组织我的程序,并决定将小文件导入 final.py。

这里我希望 DIrectorySetup 在 main 开始时启动。我希望能够调用目录。

这是我尝试过的:

class DirectorySetup: 
    '''The directory paths for the program'''
    def __init__(self):

        self.cwd = os.getcwd()
        self.Raw_data_dir= self.cwd + '\Raw_data'
        self.Clean_data_dir= self.cwd + '\Clean_data'
        self.table_dir= self.cwd + '\Tables'

def main():                      # Define the main function
    #the class with the directory
    Directory= DirectorySetup()
    os.chdir(Directory.table_dir)

    ###does other things that I removed for clarity ###



if __name__ == "__main__":
    main()

然后我在我的 final.py 程序中运行它:

import INIT_SCTFT 
import os

first=INIT_SCTFT
first.main()
first.DirectorySetup.Clean_data_dir

这给了我错误

   first.DirectorySetup.Clean_data_dir

AttributeError: type object 'DirectorySetup' has no attribute 'Clean_data_dir'

如何让 main() 保存 DirectorySetup?

【问题讨论】:

    标签: python class import main


    【解决方案1】:

    注意:

    您正在导入模块 INIT_SCTFT,然后将 first 分配给此模块。 现在首先是一个模块(您可以通过打印类型(第一个)来检查。 first.main() 将执行来自INIT_SCTFT 的主函数。主要做的是创建一个对象并更改当前目录。然后就结束了。

    然后first.DirectorySetup.Clean_data_dir 尝试从DirectorySetup 类中调用Clean_data_dir。但是DirectorySetup 类没有定义Clean_data_dirDirectorySetup 类的对象具有此属性。所以如果你想访问这个属性,你必须先创建一个对象。

    例如:

    obj = first.DirectorySetup()
    obj.Clean_data_dir
    

    编辑:

    从评论中回答您的问题。这取决于您想要达到的目标。例如,您可以创建一些返回对象列表的方法。

    class DirectorySetup: 
    '''The directory paths for the program'''
    def __init__(self):
    
        self.cwd = os.getcwd()
        self.Raw_data_dir= self.cwd + '\Raw_data'
        self.Clean_data_dir= self.cwd + '\Clean_data'
        self.table_dir= self.cwd + '\Tables'
    
    
    def create_objects():
        one = DirectorySetup()
        two = DirectorySetup()
        three = DirectorySetup()
        return one, two, three
    

    然后在 final.py 中你可以创建对象列表:objects = first.create_objects() 或者正如您提到的,您可以将其包装到某个类中:

    class my_objects:
        one = DirectorySetup()
        two = DirectorySetup()
        three = DirectorySetup()
    

    然后在 final.py 中通过:first.my_objects.one 访问它。 另请注意,如果您决定将对象放入 init 中:

    class my_objects:
        def __init__():
            one = DirectorySetup()
            two = DirectorySetup()
            three = DirectorySetup()
    

    那么首先你需要创建这个类的一个对象来访问这些变量obj = first.my_objects()然后你可以使用它:obj.one

    【讨论】:

    • 所以要访问多个对象,我是否应该将它们全部放入一个类中,然后在执行 main 之前调用它?比如: class ALL: def __init__(self): obj_a=DirectorysSetup() obj_b=Table() 然后做:oobject=first.ALL
    • 我已经编辑了我的帖子来回答这个问题。让我知道它是否是您要找的东西;)
    【解决方案2】:

    您如何在 main 之外进行操作?

    目录文件.py

    class DirectorySetup: 
        '''The directory paths for the program'''
        def __init__(self):
    
            self.cwd = os.getcwd()
            self.Raw_data_dir= self.cwd + '\Raw_data'
            self.Clean_data_dir= self.cwd + '\Clean_data'
            self.table_dir= self.cwd + '\Tables'
    
    #the class with the directory
    Directory= DirectorySetup()
    os.chdir(Directory.table_dir)
    
    

    然后从final.py访问Directory对象

    from DirectoryFile import Directory
    
    #access variable Directory's member
    print(Directory.Clean_data_dir)
    

    只有在实例化对象时调用 init() 时才会将属性添加到对象中。

    编辑:再想一想,您可以从 main() 创建一个全局变量,如下所示:

    Directory = None
    
    def main():
        global Directory
        Directory= DirectorySetup()
    

    然后从final.py访问它

    【讨论】:

    • 在我的原始代码中,我不仅想提取目录,还想提取表格等。在 main 之外执行所有这些操作会使 main 变得不那么有用。你会建议在没有 main 的情况下编写我的 INIT_SCTFT 吗?
    • 最终main() 是一种只能返回有限数量变量的方法。方法退出后,变量不返回必然销毁。
    【解决方案3】:

    您的问题是,在调用 main 函数后,python 正在垃圾收集您的 DirectorySetup 实例。

    最简单的解决方案是让 main 只返回 DirectorySetup 实例的引用,这样您就可以访问它:

    def main():                      # Define the main function
    #the class with the directory
    Directory= DirectorySetup()
    os.chdir(Directory.table_dir)
    return Directory
    ###does other things that I removed for clarity ###
    

    然后您只需将 final.py 脚本更改为:

    import INIT_SCTFT 
    import os
    
    first=INIT_SCTFT
    directory = first.main()
    directory.Clean_data_dir
    

    【讨论】:

    • 谢谢,这行得通。但是,我想检索的不仅仅是目录。我的完整 main() 还创建了一个表: Table_1= first.features(init) 所以我必须两者都返回。我想要更灵活的东西,让我可以调用我想要的东西,就好像它是类的一部分
    猜你喜欢
    • 2017-12-04
    • 1970-01-01
    • 2015-12-26
    • 2011-07-25
    • 1970-01-01
    • 2020-11-23
    • 2015-12-12
    • 2020-07-23
    • 1970-01-01
    相关资源
    最近更新 更多