从函数定义模块变量

Defining module variables from functions

我终于进入 Python,并注意到一些奇怪的事情,在 Java 中有效,但 无效在 Python.

当我输入以下内容时:

fn = ""  # Local filename storage.

def read(filename):
    fn = filename
    return open(filename, 'r').read()

我的 Atom flake8 linter 出现以下错误:

F841 - local variable 'fn' is assigned to but never used.

我假设这意味着变量是在 def 级别定义的,而不是 module 级别,我打算做。如有不妥请指正

我搜索了 Google,有多个措词,但似乎无法以正确结果显示的方式来表达它...
关于如何能够从函数级实现模块级变量定义的任何想法?

如果要将 fn 声明为全局变量 (module-level),请使用 global statement.

def read(filename):
    global fn  # <-----
    fn = filename
    return open(filename, 'r').read()

顺便说一句,; 是可选的。不要使用它。

您可以通过以下操作从函数中设置模块级变量:

import sys

def read(filename):        
    module = sys.modules[__name__]
    setattr(module, 'fn', filename)
    return open(filename, 'r').read()

然而,这是一个非常奇怪的必要性。考虑更改架构。

更新: 让我们考虑一个例子:

# module1
# uncomment it to fix NameError and AttributeError
# some_var = '' 

def foo(val):
    global some_var
    some_var = val


# module2
from module1 import *
print(some_var)  # raises NameError: name 'some_var' is not defined

foo('bar')
print(some_var)  # still raises NameError: name 'some_var' is not defined


# module3
import module1
print(module1.some_var)  # raises AttributeError: 'module' object has no attribute 'some_var'

foo('bar')
print(module1.some_var)  # prints 'bar' even without some_var = '' definition in the module1

因此,global 在导入过程中的表现并不那么明显。我认为,在 read() 调用期间手动执行 setattr(module, 'attr_name', value) 更清楚。