在Python中从其他文件调用变量
我正在尝试导入文件,情况如下 file1.py包含:在Python中从其他文件调用变量,python,Python,我正在尝试导入文件,情况如下 file1.py包含: from file2 import * username = "steven" action() def action(): print username file2.py包含: from file2 import * username = "steven" action() def action(): print username 但是我无法打印用户名,因为变量“username”是在file1中声明的,而不
from file2 import *
username = "steven"
action()
def action():
print username
file2.py包含:
from file2 import *
username = "steven"
action()
def action():
print username
但是我无法打印用户名,因为变量“username”是在file1中声明的,而不是在file2中声明的(因为函数使用该变量)
这不是实际的代码,但我是否可以在file2的函数中不使用file1中的变量?但是
file2.py
没有导入file1.py
;它怎么知道username
甚至存在
顺便说一句,我试图避免代码中的循环依赖关系(即模块x导入模块y,模块y导入模块x),因此简单地将
file1
导入file2
可能不是最佳解决方案。否,file2无法访问file1中的全局变量而不显式导入它们。这实际上是一件好事,因为否则,一个导入了大量模块的项目很容易意外地覆盖彼此的数据
为什么不将用户名作为方法的参数
file1.py:
from file2 import action
username = "steven"
action(username)
file2.py:
def action(username):
print username
按照您的意愿,需要file1导入file2,反之亦然——在普通代码中,这将导致循环导入,而循环导入显然不起作用 但除此之外,如果文件上的函数、类或方法需要了解导入它们的文件上下文中的数据,那么正确的做法是将这些数据作为函数参数传入 在您的情况下,您的“操作”功能应该是:
def action(username):
print username
在文件1中:
from file2 import action
username = "steven"
action(username)
(您还应该避免使用“import*”,因为它在读取代码时隐藏了名称的来源,因此很难维护)
当然,Python作为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()
现在,为了给你一个完整的答案-这里有一些代码可以做你想做的-但你不做-修改yoru函数来获取参数
可以做的是使用一个函数来读取调用它的地方的全局变量。这不仅是“一个不好的做法”-它只是错误的,除了一些非常有文档记录的框架,其中“神奇的变量名”用于配置。即使我发现一个框架有这样的坏习惯,我也倾向于修补它的函数,以便通过函数调用显式地传递配置
from inspect import currentframe
def action():
caller_frame = current_frame(1)
caller_globals = caller_frame.f_globals
print caller_globals["username"]
最好使用类,因为它们很容易扩展: file1.py:
from file2 import ExtendedClass
class MyClass(object, ExtendedClass):
def __init__(self):
Object.__init__(self)
self.username = 'steven'
class ExtendedClass:
def action(self):
print self.username
file2.py:
from file2 import ExtendedClass
class MyClass(object, ExtendedClass):
def __init__(self):
Object.__init__(self)
self.username = 'steven'
class ExtendedClass:
def action(self):
print self.username
尽管存在一些不太好的方法并解决了您的问题,但一旦使用它们,您就会喜欢类。更好的方法是不依赖另一个模块的全局变量,只需将名称传递到
file2.action()函数中即可:
file1.py
file2.py
太棒了,谢谢!所以我不必输入“import*”?我可以直接导入文件吗?没错。如果您只是导入文件2
,那么您将需要使用file2.
限定文件2中的所有名称,例如file2.action
示例。但这是一件好事,因为您知道操作的方向。在本例中,任何使用file1.py
中变量的file2.py
函数都应该有一个参数来获取它?循环依赖在Python中甚至不起作用-不需要几个“if”在模块主代码中的,在导入时知道它的。