在Python中从其他文件调用变量

在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中声明的,而不

我正在尝试导入文件,情况如下

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中声明的,而不是在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”在模块主代码中的,在导入时知道它的。