如果 var 位于同一范围内的 if 语句中,我无法从 for 循环访问 var

I can't access to the var from a for loop if it inside an if statement that is in the same scope

提问人:TWISTER_FROSTE 提问时间:6/21/2023 最后编辑:TWISTER_FROSTE 更新时间:6/21/2023 访问量:52

问:

我的项目需要一些帮助。


问题是我无法从 for 循环访问变量,该变量位于同一范围内的 if 语句中。

下面是一个示例:

import os

temp_variable = [0, 1, 2, 3]

if len(temp_variable) > 1:
      temp_variable = temp_variable[0] # This is a variable

for element in os.listdir(temp_variable) # here the "temp_variable is list instead of a integer  
     dosomething()

这是一个源代码:

def not_around(gpath, home_path) -> list[str]:
    dirs_for_filter: list[str] = []

    for root, Gdir, Gfiles in os.walk(home_path):
            for i in range(len(Gdir)):
                if Gdir[i] in [gpath.split('/')[-1]]:

                    gpath: str = root[0:] + '/' + Gdir[i]
                    print(gpath)
                    prossesed_copy_path: str = gpath
                    dirs_for_filter.append(prossesed_copy_path)
    return dirs_for_filter


def filter(arg_path: str =WD, *, is_around: bool =True, skipped: typing.Union[None, list[str]] =None):

    path = arg_path
    path_ = path
    print("path from start: " + path)
    
    input_copy_path: str = path

    temp_files: list[str] = []
    temp_dirs: list[str] = []
    repeted_dirs: list[str] = []

    if not is_around:
        repeted_dirs = not_around(path, '/home')
        path = repeted_dirs

    if len(path) > 1: # The if statement 


        print(f"""There a {len(repeted_dirs)} file that have the same name of {input_copy_path}.""")
        i: int = 1
        for dir in repeted_dirs:
            if i == 1:
                print(f"\n\n    {i}. The {input_copy_path} in [  {repeted_dirs[i]}  ] folder")
                i += 1
                continue
            print(f"    {i}. The {input_copy_path} in [  {repeted_dirs[i - 2]}  ] folder")
            i += 1
        print(f"    {i}. All of them\n")
        try:
            response: int = int(input('Choose one of the available options by passing it\'s number: '))
            response -= 1
        except ValueError:
            print("This is not in the valed.")

        if response == len(repeted_dirs) + 1:
            print("This future is not available yat.")  #   Make this dream in reality :) 
            exit(1)

        path_ = path[response]

    for element in os.listdir(path=path_): # The for loop


        if skipped != None:
            if element in [file_ for file_ in skipped]:  # ["voldemorts.py", "salt.salt", "password.txt"]
                continue

        if element in ["voldemorts.py", "salt.salt"]:
            continue
        
        element = os.path.join(path, element)
            
        if os.path.isfile(element):
            temp_files.append(element)

        if os.path.isdir(element):
            temp_dirs.append(element)

    for i in range(len(temp_files)):
        files.append(temp_files[i])

    for i in range(len(temp_dirs)):
        dirs.append(temp_dirs[i])

    if temp_dirs != []:

        for i in range(len(temp_dirs)):
            filter(os.path.join(path, temp_dirs[i]))

        return dirs, files

    return temp_dirs, temp_files


if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser(description="""File Encryptor Script with a Password""")
    parser.add_argument("file", help="File to encrypt/decrypt")
    parser.add_argument("-s", "--salt-size", help="If this is set, a new salt with the passed size is generated", type=int)
    parser.add_argument("-e", "--encrypt", action="store_true",
                        help="Whether to encrypt the file, only -e or -d can be specified.")
    parser.add_argument("-d", "--decrypt", action="store_true",
                        help="Whether to decrypt the file, only -e or -d can be specified.")
    parser.add_argument("-i", "--is-around", help="If is around, the tool will encrypt/decrypt all the files that is with it in the same folder", type=bool)
    parser.add_argument("-k", "--skipped", help="If there is any file you want to ignored it", type=list[str])

    args = parser.parse_args(args=['poeple info', '--encrypt', '--salt-size', '128'])
    file = args.file

    if args.encrypt:

        try:
            password = getpass.getpass("Enter the password for encryption: ")
        except KeyboardInterrupt:
            print('\n\nMADE BY Muhammed Alkohawaldeh')
            exit(1)

    elif args.decrypt:

        try:
            password = getpass.getpass("Enter the password you used for encryption: ")
        except KeyboardInterrupt:
            print('\n\nMADE BY Muhammed Alkohawaldeh')
            exit(1)

    if args.salt_size:
        key = generate_key(password, salt_size=args.salt_size, save_salt=True)
    else:
        key = generate_key(password, load_existing_salt=True)

    encrypt_ = args.encrypt
    decrypt_ = args.decrypt

    if encrypt_ and decrypt_:
        raise TypeError("Please specify whether you want to encrypt the file or decrypt it.")
    elif encrypt_:
        if args.is_around:
            
            if args.skipped:
                for _file in filter(file, is_around=True, skipped=args.skipped)[1]:
                    encrypt(_file, key)

            for _file in filter(file, is_around=True, skipped=None)[1]:
                encrypt(_file, key)

        elif args.skipped:
            for _file in filter(file, is_around=False, skipped=args.skipped)[1]:
                    encrypt(_file, key)
        else:
            for _file in filter(file, is_around=False, skipped=None)[1]:
                    encrypt(_file, key)

        print("File Encrypted successfully")

    elif decrypt_:
        if args.is_around:
            
            if args.skipped:
                            for _file in filter(file, is_around=True, skipped=args.skipped)[1]:
                                if decrypt(_file, key):
                                    print(f"[{_file.split('/')[-1]}] decrypted successfully")
                                else:
                                    print("Invalid token, most likely the password is incorrect")
                                    exit(1)

            for _file in filter(file, is_around=True, skipped=None)[1]:
                    if decrypt(_file, key):
                        print(f"[{_file.split('/')[-1]}] decrypted successfully")
                    else:
                        print("Invalid token, most likely the password is incorrect")
                        exit(1)
                    
        elif args.skipped:
            for _file in filter(file, is_around=False, skipped=args.skipped)[1]:
                    if decrypt(_file, key):
                        print(f"[{_file.split('/')[-1]}] decrypted successfully")
                    else:
                        print("Invalid token, most likely the password is incorrect")
                        exit(1)
        else:
            for _file in filter(file, is_around=False, skipped=None)[1]:
                    if decrypt(_file, key):
                        print(f"[{_file.split('/')[-1]}] decrypted successfully")
                    else:
                        print("Invalid token, most likely the password is incorrect")
                        exit(1)
    else:
        raise TypeError("Please specify whether you want to encrypt the file or decrypt it.")

这是错误:

Traceback (most recent call last):
  File "/media/twister_froste/CAE8-23EA/ransomware/voldemorts.py", line 234, in <module>
    for _file in filter(file, is_around=False, skipped=None)[1]:
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/media/twister_froste/CAE8-23EA/ransomware/voldemorts.py", line 146, in filter
    for element in os.listdir(path=path_):
                                   ^^^^^
UnboundLocalError: cannot access local variable 'path_' where it is not associated with a value

我试过谷歌,但仍然没有结果-_-

任何未完成的代码都是因为代码太长,所以我剪掉了它。

感谢您的阅读。


编辑

  1. 我删除了无用的 Global 语句
  2. 我将 [] 重命名_path [arg_path]
  3. 为变量赋值 [path_] --> path_ = path

但是我仍然有一个错误说:

Enter the password for encryption: 
path from start: poeple info
Traceback (most recent call last):
  File "/media/twister_froste/CAE8-23EA/ransomware/voldemorts.py", line 233, in <module>
    for _file in filter(file, is_around=False, skipped=None)[1]:
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/media/twister_froste/CAE8-23EA/ransomware/voldemorts.py", line 145, in filter
    for element in os.listdir(path=path_):
                   ^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'poeple info'
python 变量 scope global-variables local

评论

0赞 TWISTER_FROSTE 6/21/2023
@john-戈登,我失去了希望,所以我尝试了一切,但都导致了相同的结果。
0赞 tdelaney 6/21/2023
该错误意味着在尝试使用变量之前未为其赋值。你在声明中有。那么,如果条件是,并且该赋值从未运行怎么办?然后你得到那个错误。path_ = path[response]ififFalse
0赞 tdelaney 6/21/2023
请注意,在模块级别没有任何意义。 在单个函数中用于将变量声明为仅该函数的全局变量。global path, ....global
0赞 Davis Herring 6/21/2023
如果我有 、 和 都在同一个(长)函数中,我也会有错误。path_pathpath_

答:

1赞 Hamza Chennaq 6/21/2023 #1

您必须在 if 语句之前声明它

path_ = None

if len(path) > 1:
0赞 John Gordon 6/21/2023 #2

以下是演示该问题的函数的简化版本:filter()

def filter(_path: str =WD, *, is_around: bool =True, skipped: typing.Union[None, list[str]] =None):

    ... code deleted
    if len(path) > 1: # The if statement 
        ... code deleted
        path_ = path[response]

    for element in os.listdir(path=path_): # The for loop

问题在于,只有当语句为 true 时才定义。path_if len(path) > 1

当该语句为 false,因此未执行其下面的代码时,该语句未定义。path_

因此,您的代码遇到了 false 的情况,因此该变量根本不存在。if len(path) > 1path_