我正在尝试导入文件,情况就是这样。
file1.py包含:
from file2 import *
username = "steven"
action()
file2.py包含:
def action():
print username
但我无法打印用户名,因为变量'username'在file1中声明但不在file2中声明(因为该函数使用变量)
这不是实际的代码,但是我不能在file2的函数中使用file1中的变量吗?
答案 0 :(得分:5)
更好的方法是不依赖于另一个模块的全局变量,只需将名称传递给file2.action()
函数:
import file2
username = "steven"
file2.action(username)
def action(name):
print name
答案 1 :(得分:2)
你想要的方式是什么,需要file1导入文件2,反之亦然 - 在普通代码中,这将导致循环导入,这显然不起作用。
但除此之外,如果文件中的函数,类或方法需要知道导入它们的文件上下文中的数据,那么正确的做法是将这些数据作为函数参数传递。 / p>
在您的情况下,您的“操作”功能应为:
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"]
答案 2 :(得分:1)
但file2.py
未导入file1.py
;怎么知道username
甚至存在?
顺便提一下,我尝试避免代码中的循环依赖(即模块x导入模块y和模块y导入模块x),因此只需将file1
导入file2
可能不是最佳解决方案
答案 3 :(得分:1)
不,file2无法在不明确导入的情况下访问file1中的全局变量。这实际上是一件好事,因为否则,导入一堆模块的项目很容易被意外地覆盖每个人的数据。
为什么不将用户名作为方法的参数?
file1.py:
from file2 import action
username = "steven"
action(username)
file2.py:
def action(username):
print username
答案 4 :(得分:0)
最好使用类,因为它们很容易扩展:
<强> file1.py 强>:
from file2 import ExtendedClass
class MyClass(object, ExtendedClass):
def __init__(self):
Object.__init__(self)
self.username = 'steven'
<强> file2.py 强>:
class ExtendedClass:
def action(self):
print self.username
即使有一些hacky方法存在并解决你的问题,你一旦使用它们就会欣赏它们。