从文件 b.py 中的函数附加到文件 a.py 后访问变量

Posted

技术标签:

【中文标题】从文件 b.py 中的函数附加到文件 a.py 后访问变量【英文标题】:Accessing a variable after being appended in file a.py from a function in file b.py 【发布时间】:2021-12-18 14:20:59 【问题描述】:

我在尝试从文件 b.py 中的函数访问文件 a.py 中的变量时遇到问题。我尝试在互联网上四处寻找,但找不到任何东西,或者我不知道如何寻找我需要的东西。我还尝试创建另一个文件并更新文件 c.py 中的变量,但文件 b.py 仍然看到变量的第一次初始化。我尝试更新文件 a.py 中的变量,然后在 b.py 的函数中导入 a.py。

文件 a.py

var = []


def run():

    a.welcome()

    while True:

        menu = a.menu()

        if menu == 1:

            def retrieve_path(source_path):

                """The function takes 1 parameter and checks if the file name exist as well as the file path

                    Adds the csv data to a variable

                source_path (str): Path against whom to check for validity

                """
                if not source_path:

                    print("Invalid file name, Please try again\n")
                    return

                else:
                    import os
                    isFile = os.path.isfile(source_path)
                    if not isFile:
                        print("Invalid file path\n")
                        return

                    else:
                        with open(source_path, "r") as csv_file:
                            csv_reader = csv.reader(csv_file, delimiter=',')
                            for line in csv_reader:
                                line = list(line)
                                var.append(line)



if __name__ == "__main__":
    run()

文件 b.py

我试过这样,但我得到了变量var = []的第一次初始化

我首先从文件 a.py 更新了 var,然后我尝试在文件 b.py 中使用下面的函数,但结果仍然相同。

from a import var
from a import *
import a

def a_function():

    from a import var

    from a import *

    import a

    print(var)

    print(a.var)

这会打印 var which = [] 的第一次初始化,而不是在它被附加之后。

如果我从 a 打印 var,则从函数内部打印它更新。

如果我从 a 打印 var,则从函数外部打印它更新。

我不明白的是,为什么更新后,导入到b里面,还是得到第一次初始化。调试器也没有帮助。 我可以通过在 b.py 中添加函数 retrieve_path 然后将数据附加到文件 b.py 中的另一个变量中来解决它,但我想知道它为什么不导入 var 更新数据。

文件 b.py

var2 = []

def retrieve_path(source_path):

                """The function takes 1 parameter and checks if the file name exist as well as the file path

                    Adds the csv data to a variable

                source_path (str): Path against whom to check for validity

                """
                if not source_path:

                    print("Invalid file name, Please try again\n")
                    return

                else:
                    import os
                    isFile = os.path.isfile(source_path)
                    if not isFile:
                        print("Invalid file path\n")
                        return

                    else:
                        with open(source_path, "r") as csv_file:
                            csv_reader = csv.reader(csv_file, delimiter=',')
                            for line in csv_reader:
                                line = list(line)
                                var.append(line)
                                var2.append(line)

如果这是解决方案之一,我没有使用 Class 的原因是因为我对 Class 了解不多,暂时不知道如何正确使用它们。

我希望我说得非常明确,并且您理解我的困境。另外,请记住我刚开始学习 Python,因此非常欢迎新的解释和解决方案。

【问题讨论】:

你应该想知道 a.py 中的 run 函数在哪里被调用过。根据您的代码,它永远不会... 我的坏 Serge,我在文件末尾有: if name == "main": run() 用你自己的话来说,if __name__ == "__main__":是什么意思?您希望run 函数在您import a 时运行吗?为什么或者为什么不? (提示:此代码专门用于确保代码不会在您import 模块时运行,但仅在它是起点时运行。) 当我引起你的注意时,请阅读***.com/help/minimal-reproducible-example。 【参考方案1】:

正确的方法是在访问var之前调用run函数。要么

import a
a.run
print(a.var)

或:

from a import var, run
run
print(var)

import 语句只运行模块的内容,而不是其中声明的函数。


运行脚本的惯用方式确实是您在 a.py 中所拥有的:

if __name__ == "__main__":
    run()

如果您将文件用作带有python a.py 的脚本,则会调用run 函数,因为由解释器直接 启动的文件将被命名为__main__。但是导入的时候是按照文件名来命名的。所以这里应该是a 而不是main。换句话说,当a.py 被导入时,run 永远不会被调用。

一种可能性是用run的无条件调用来结束a.py:

...
                                line = list(line)
                                var.append(line)

run()

它应该是无害的,因为 Python 会跟踪已经导入的模块,并且即使模块是从多个地方导入的,run 也应该只调用一次。然而这将是一种反模式,因为按照惯例 import 应该尽可能少地产生副作用,而 run 似乎会执行很多操作。

【讨论】:

但问题是,var 在 run 函数之外。当 run() 运行时,它会更新全局变量 var。为什么需要在文件 b 中导入运行?谢谢 @FloreaConstantinCristian:请看我的编辑...【参考方案2】:

好的,这只是我完成的学校项目的一部分,但我想让这部分的记录与我为年级所做的有点不同。如果某些功能没有意义,那是因为项目没有完成。我唯一关心的是记录变量。

main.py

import tui, csv

records = []

def run():

    tui.welcome()

    while True:

        menu = tui.menu()

        if menu == 1:
            
            def retrieve_path(source_path):
                """The function takes 1 parameter and checks if the file name exist as well as the file path
                    Adds the csv data to a variable
        
                source_path (str): Path against whom to check for validity
                """
                if not source_path:
                    print("Invalid file name, Please try again\n")
                    return
                else:
                    import os
                    isFile = os.path.isfile(source_path)
                    if not isFile:
                        print("Invalid file path\n")
                        return
                    else:
                        with open(source_path, "r") as csv_file:
                            csv_reader = csv.reader(csv_file, delimiter=',')
                            for line in csv_reader:
                                line = list(line)
                                records.append(line)

            tui.started("Data Loading")
            retrieve_path(tui.source_data_path())
            tui.completed("Data Loading")

        if menu == 2:
            tui.started("Retrieving data")
            process_menu = tui.process_type()
            tui.completed("Retrieving data")

            if process_menu == 1:
                tui.started("Retrieving entity name")
                tui.entity_name()
                tui.completed("Retrieving entity name")

            if process_menu == 2:
                tui.started("Retrieving entity details")
                entity, cols = tui.entity_details()
                tui.list_entity(entity, cols)
                tui.completed("Retrieving entity details")

        if menu == 3:
            print(tui.main_records)
        if menu == 4:
            break


if __name__ == "__main__":
    run()

第二个文件是:

tui.py

def welcome():

    message = "System Management"
    print("*" * len(message))
    print(message)
    print("*" * len(message))


def menu():

    main_menu = "-"

    while main_menu != "0":
        if main_menu == "-":
            print('Main Menu:'
                  '\n1. Load Data'
                  '\n2. Process Data'
                  '\n3. Visualise Data'
                  '\n4. Save Data'
                  '\n0. Exit')

        elif main_menu in "1234":
            return int(main_menu)

        elif main_menu not in "1234":
            error(main_menu)
            return None
        else:
            print('Main Menu:'
                  '\n1. Load Data'
                  '\n2. Process Data'
                  '\n3. Visualise Data'
                  '\n4. Save Data'
                  '\n0. Exit')

        main_menu = input()


def started(operation):


    print(" has started.\n".format(operation))


def completed(operation):

    print(" has completed.\n".format(operation))


def error(error_msg):


    print("Error!  is not a valid option.".format(error_msg))


def source_data_path():


    print("Please enter the path to the source data file:")

    source_path = input()

    if ".csv" not in source_path:
        return None
    else:
        return source_path


def process_type():

    process_menu = "-"

    while process_menu != "0":
        if process_menu == "-":
            print('Process Menu:'
                  '\n1. Retrieve entity'
                  '\n2. Retrieve entity details'
                  '\n3. Categorise entities by type'
                  '\n4. Categorise entities by gravity'
                  '\n5. Summarise entities by orbit'
                  '\n6. Return to Main Menu')
        elif process_menu == "6":
            menu()
            return None

        elif process_menu in "12345":
            return int(process_menu)

        elif process_menu not in "12345":
            error(process_menu)
            return None
        else:
            print('Process Menu:'
                  '\n1. Retrieve entity'
                  '\n2. Retrieve entity details'
                  '\n3. Categorise entities by type'
                  '\n4. Categorise entities by gravity'
                  '\n5. Summarise entities by orbit'
                  '\n6. Return to Main Menu')

        process_menu = input()


def entity_name():

    entity = input("Please enter the name of an entity: ")
    return entity


def entity_details():

    entity = input("Please enter the name of an entity: ")
    indexes = input("Please enter the indexes number (e.g. 0,1,5,7):\n")


    return entity, list(indexes)

请有 我第一次做这个项目时,我将 def retrieve_path(source_path): 添加到 tui.py 并且效果很好。

我不太明白为什么要附加变量记录,我可以从 run 内部和 run 函数外部打印它,但在 tui.py 中我只得到 records = [] 以及如何解决这个问题没有在 tui.py 中创建函数 retrieve_path

这是当时对我们的要求,这样做不是我个人的选择。

我很抱歉没有在这里粘贴所有内容并错误输入了一些部分,例如 == _ main _ .

【讨论】:

以上是关于从文件 b.py 中的函数附加到文件 a.py 后访问变量的主要内容,如果未能解决你的问题,请参考以下文章

3. python中的包和库

python如何在某.py文件中调用其他.py内的函数

根据扩展名将git repo文件移动到子文件夹

python如何调用另一个py文件的所有函数

Python不同目录下的.py文件调用问题

python中的包