无法从外部范围访问变量 (Python)

Cannot access variable from outer scope (Python)

所以我正在尝试创建一个 CLI,但我在使用 'cd' 命令时遇到了一些错误。我无法从我的 cd 命令访问 'target_path' 变量。这是 CLI 的代码:

import os, colorama

ERROR_COLOR = colorama.Back.RED + colorama.Fore.BLACK

user = os.getlogin()
target_path = f'C:\Users\{user}'

class Commands:
    def __init__(self):
        raise RuntimeError("Cannot instantiate class 'Commands'")


    @staticmethod
    def help(cmd=None):
        cmd_help_msgs = {
            'help': \
    """
    HELP:
        USAGE:
            help [command: str]

        DESCRIPTION:
            Prints out the description and usage of a command.
            If command is not passed, it prints out the help messages of all commands
    """,
            'cls': \
    """
    CLS:
        USAGE:
            cls
            
        DESCRIPTION:
            Clears the terminal
    """,
            'exit': \
    """
    EXIT:
        USAGE:
            exit
        
        DESCRITPION:
            Quits the program
    """,
        'echo': \
    """
    ECHO:
        USAGE:
            echo <msg: str>
            
        DESCRIPTION:
            Prints out msg
    """
        }

        help_msg = f"""
IMPORTANT: [] = optional parameter, <> = mandatory parameter

COMMANDS:
"""

        if cmd is None:
            print(help_msg, end='')
            for val in cmd_help_msgs.values():
                print(val, end='')
        else:
            try:
                print(help_msg, end='')
                print(cmd_help_msgs[cmd])
            except:
                print(f"{ERROR_COLOR}'{cmd}' is not recognized as a valid command! Do 'help' to see all valid commands{colorama.Style.RESET_ALL}")
                return

        print('\n')


    @staticmethod
    def cls():
        os.system('cls')


    @staticmethod
    def exit():
        exit(0)


    @staticmethod
    def echo(msg=''):
        if msg == '':
            print(ERROR_COLOR + "Missing required argument 'msg'" + colorama.Style.RESET_ALL)
            return

        print(msg)


    @staticmethod
    def cd(directory=''):
        if directory == '':
            print(target_path)
            return

        if directory[1] != ':':
            if os.path.exists(target_path + directory) and os.path.isdir(target_path + directory):
                target_path += directory
            else:
                print(f"{directory} is not a valid directory")
        else:
            if os.path.exists(directory) and os.path.isdir(directory):
                target_path = directory
            else:
                print(f"{directory} is not a valid directory")


command_list = [func for func in dir(Commands) if callable(getattr(Commands, func)) and not func.startswith('__')]

os.system('cls')

while True:
    command_has_kws = False

    command = input(f'[{target_path}]{colorama.Fore.CYAN} @ {colorama.Fore.LIGHTBLUE_EX}').strip().split(' ')
    print(colorama.Style.RESET_ALL, end='')

    for i in range(len(command)):
        command[i] = command[i].strip()

        if command[i].startswith('-'):
            command_has_kws = True

    if command[0] in command_list:
        try:
            if not command_has_kws:
                getattr(Commands, command[0])(*command[1:])
            else:
                # REMINDER: Type 'getattr(Commands, command[0]).__code__.co_varnames[:getattr(Commands, command[0]).__code__.co_argcount]' to get the parameters of a command
                pass # TODO: Implement keywords
        except TypeError:
            print(f"{ERROR_COLOR}Too many or too little arguments were passed to '{command[0]}'{colorama.Style.RESET_ALL}")
    else:
        print(f"{ERROR_COLOR}'{command[0]}' is not recognized as a valid command! Do 'help' to see all valid commands{colorama.Style.RESET_ALL}\n")

以下是您应该关注的两件事:

target_path = f'C:\Users\{user}'

并且:

@staticmethod
    def cd(directory=''):
        if directory == '':
            print(target_path)
            return

        if directory[1] != ':':
            if os.path.exists(target_path + directory) and os.path.isdir(target_path + directory):
                target_path += directory
            else:
                print(f"{directory} is not a valid directory")
        else:
            if os.path.exists(directory) and os.path.isdir(directory):
                target_path = directory
            else:
                print(f"{directory} is not a valid directory")

这里还有错误信息:

Traceback (most recent call last):
  File "C:\Users\[REDACTED]\Desktop\Crabby_CLI\main.py", line 132, in <module>
    getattr(Commands, command[0])(*command[1:])
  File "C:\Users\[REDACTED]\Desktop\Crabby_CLI\main.py", line 102, in cd
    if os.path.exists(target_path + directory) and os.path.isdir(target_path + directory):
UnboundLocalError: local variable 'target_path' referenced before assignment

信息: 口译员 - Python 3.8 OS - Windows 10 编辑器 - PyCharm 社区版

local variable 'target_path' referenced before assignment 此错误表明您在分配任何值之前试图在您的一个函数中访问 target_path 如果我的理解是正确的,您想要使用全局 target_path, 你已经在这些函数中设置在顶部。

如果这是正确的,那么您需要告诉您的函数使用全局变量。

解法:

在每个使用 'target_path' 变量的函数中,在开头放置这一行

def abc():
    # add this line
    global target_path
    ...
    ...
    # now use `target_path` here