Python中是否有办法管理范围,以便调用函数中的变量在被调用函数中可见?我想要类似下面的内容
z = 1
def a():
z = z * 2
print z
def b():
z = z + 1
print z
a()
print z
b()
我想获得以下输出
2
4
2
这个问题的真正解决方案就是将z作为变量传递。我不想这样做。
我拥有庞大而复杂的代码库,拥有各种专业水平的用户。他们目前接受过传递一个变量的训练,现在我必须添加另一个变量。我不相信他们通过所有函数调用始终传递第二个变量,所以我正在寻找维护接口的替代方案。这是不可能的。
答案 0 :(得分:7)
我认为这就是你要找的东西。如果您控制内部函数,并且您正在寻找的变量已经在调用链中的某个范围内,但您不希望您的用户必须在调用本身中包含该变量。您显然不需要global
关键字,因为您不希望内部分配影响外部范围。
使用inspect
模块可以访问调用上下文。 (但是,请注意它有点脆弱。你应该只使用CPython无螺纹。)
import inspect
def calling_scope_variable(name):
frame = inspect.stack()[1][0]
while name not in frame.f_locals:
frame = frame.f_back
if frame is None:
return None
return frame.f_locals[name]
z = 1
def a():
z = calling_scope_variable('z')
z = z * 2
print z
def b():
z = calling_scope_variable('z')
z = z + 1
print z
a()
print z
b()
这确实给出了正确答案:
2
4
2
答案 1 :(得分:5)
这可能是课程的正确位置:
class MyClass(object):
def __init__(self, z):
self.z = 1
def a(self):
self.z = self.z * 2
print self.z
def b():
self.z = self.z + 1
print self.z
self.a()
print self.z
您可以使用全局变量获得相同的效果,但我建议您创建自己的独立命名空间(例如使用类)并将其用于范围。
答案 2 :(得分:2)
一般来说,最好的解决方案只是传递价值 - 这将更加可预测和自然,更易于使用和调试:
def a(z):
z = z * 2
print z
def b():
global z
z = z + 1
print z
a(z)
print z
b()
您可以在a()
中定义b()
并执行类似操作:
def b():
global z
z = z + 1
print z
def a():
z = z * 2
print z
a()
print z
但是,这并不是最佳选择。
答案 3 :(得分:2)
我不太明白你想要达到的目标,但这会打印2,4,2:
z = 1
def a():
global z
y = z * 2
print y
def b():
global z
z = z + 1
print z
a()
print z
b()
答案 4 :(得分:2)
这有点难看,但它避免使用全局变量,我测试了它并且它有效。使用找到的here选定答案中的代码,函数getSetZ()
有一个“静态”变量,可用于存储传递给它的值,然后在调用函数时检索None
作为参数。某些限制是它假定None
不是z的可能值,并且您不使用线程。您只需记得在每次调用希望调用函数getSetZ()
可用的函数之前调用z
,并从getSetZ()
中获取值并将其放入在该函数的局部变量中。
def getSetZ(newZ):
if newZ is not None:
getSetZ.z = newZ
else:
return getSetZ.z
def a():
z = getSetZ(None)
z = z * 2
print z
def b():
z = getSetZ(None)
z = z + 1
print z
getSetZ(z)
a()
print z
getSetZ.z = 0
getSetZ(1)
b()
我希望这会有所帮助。