在Python中从其他文件调用变量
我正在尝试导入文件,情况是这样的。
file1.py 文件里包含:
from file2 import *
username = "steven"
action()
file2.py 文件里包含:
def action():
print username
但是我无法打印用户名,因为变量 'username' 在 file1 中声明,但在 file2 中没有(因为函数使用了这个变量)。
这不是实际的代码,但我不能在 file2 的函数中使用 file1 的变量吗?
5 个回答
但是,file2.py
并没有导入file1.py
,那它怎么会知道username
这个东西存在呢?
顺便说一下,我尽量避免在我的代码中出现循环依赖(也就是说,模块x导入模块y,而模块y又导入模块x),所以单纯地把file1
导入到file2
可能不是最好的解决办法。
你想要的那种方式,需要文件1导入文件2,同时文件2也要导入文件1。这样做在代码中会导致循环导入,这种情况是行不通的。
除此之外,如果你在一个文件中的函数、类或方法需要知道另一个文件中的数据,正确的做法是把这些数据作为函数的参数传进去。
在你的例子中,你的“action”函数应该是:
def action(username):
print username
然后在文件1中:
from file2 import action
username = "steven"
action(username)
(你还应该避免使用“import *”,因为这样会让人不清楚名字是从哪里来的,读代码时会很难维护)
当然,Python有它自己的方式来解决你想要的事情——你可以创建一个特殊的装饰器,用在你导入的函数上,这样可以从另一个文件重建你的函数,并指向当前模块的全局变量,但这样做其实没什么意义。
在面向对象编程(OOP)中,有一种比较特殊的情况,和你想做的有点像——就是一个方法使用类的属性。如果这个属性在子类中被重写了,那么这个方法(即使是原来的父类方法)也会使用新的属性值,比如:
class A(object):
username = ""
def action(self):
print self.__class__.username
而类B可以在其他文件中定义,正如你所想的那样:
from file2 import A
class B(A):
username = "Mike"
b = B()
b.action()
现在,为了给你一个完整的答案,这里有一些代码可以实现你想要的功能——但_不要这样做_,请修改你的函数,让它们接收参数。
可以做的是创建一个函数来读取调用它的地方的全局变量。这不仅仅是“不好的做法”,而且是错误的,除非在一些文档非常完善的框架中使用了“魔法变量名”来进行配置。即使我发现一个框架有这样的坏习惯,我也倾向于修补它的函数,以便我可以通过函数调用明确地传递配置。
from inspect import currentframe
def action():
caller_frame = current_frame(1)
caller_globals = caller_frame.f_globals
print caller_globals["username"]
一个更好的方法是不要依赖其他模块中的全局变量,而是直接把名字传递给 file2.action()
这个函数:
file1.py
import file2
username = "steven"
file2.action(username)
file2.py
def action(name):
print name