局部变量没有传递给在单独加载的类python3中定义的函数



我有一个主python文件:

mainFile.py:

a = 1
b = 2
from MyClass import MyClass # import class here as variables used by MyClass will be defined above.
test = MyClass()
test.afunction()

并且类定义为:

MyClass.py:

class MyClass():
def afunction(self):
return a + b

我希望在运行mainFile.py时返回1+2=3。然而,我得到以下错误:

return a + b
NameError: name 'a' is not defined

我可以在一个文件中简单地做到这一点:

a = 1
b = 2
class MyClass():
def afunction(self):
return a + b
test = MyClass()
test.afunction()

运行此操作将返回3。但是,考虑到类定义的长度,我希望它在一个单独的文件中。

我尝试过声明global a,但它仍然看不到ab。将ab定义为afunction(self, a, b):的输入是不实际的。(afunction被包中的另一个函数调用,我不想在另一个包的官方函数中编辑对afunction的调用(。

如果需要,很乐意提供更多信息。我也很乐意提供实际的例子,而不是这个抽象的MWE:我正在使用FPDF模块用python制作PDF报告。该类定义了headerfooter,其中添加了图像、标题和作者。logo_pathtitleauthor都设置在主python脚本中。如果我将类定义移动到一个单独的文件中,那么它显然看不到变量logo_pathtitleauthor

你不可能完全做你想做的事情(如果没有大量的反思(。不过,你确实有几个选择:

将变量放入MyClass的构造函数(推荐(

MyClass.py

class MyClass:
def __init__(self, a=1, b=2):
self.a = a
self.b = b
def afunction(self):
return a + b

mainFile.py

from MyClass import MyClass
a = 1
b = 2
test = MyClass(a, b)
test.afunction()

从mainFile.py中设置MyClass.py中的变量

MyClass.py

a = 1
b = 2
class MyClass:
def afunction(self):
return a + b

mainFile.py

import MyClass
MyClass.a = 1
MyClass.b = 2
test = MyClass()
test.afunction()

如果您真的想从MyClass.py中访问mainFile.py的变量

这是在这里,以防有人知道这是他们想做的事情,并发现这个问题。虽然确实存在这样做的有效用例,但它们很少。(这是前面提到的"荒谬的反射量"(

MyClass.py

from contextlib import suppress
import sys

_this_mod = sys.modules[__name__]

class MyClass:
def afunction():
for mod in sys.modules.values():
for attr in dir(mod):
if ((getattr(mod, attr) is _this_mod and mod is not _this_mod)
or getattr(mod, attr) is afunction):
with suppress(AttributeError):
return getattr(mod, 'a') + getattr(mod, 'b')

mainFile.py

import MyClass
a = 1
b = 2
test = MyClass.MyClass()
test.afunction()

# or

from MyClass import MyClass
a = 1
b = 2
test = MyClass()
test.afunction()

您可以按以下方式进行操作。只需将变量传递给构造函数,并确保构造函数已准备好处理它们。作为奖励,您可以添加一个setter,这样您就可以在一行/调用中设置参数。

myscript.py

class MyClass:
@property
def params(self):
return self.a, self.b

@params.setter
def params(self, data):
self.a, self.b = data
def __init__(self, **kwargs):
self.a = 0
self.b = 0
#transpose kwargs to self
for key in kwargs.keys():
self.__dict__[key] = kwargs[key]
def afunc(self):
return self.a + self.b

main.py…或任何

from myscript import MyClass
a = 1
b = 2
test = MyClass(a=a,b=b)
c = test.afunc()
print(c) #3
#change a and b example
test.params = (60, 20)
c = test.afunc()
print(c) #80

或者,如果你只有几个夸尔格,这会更干净。

class MyClass:
@property
def params(self):
return self.a, self.b

@params.setter
def params(self, data):
self.a, self.b = data
def __init__(self, a=0, b=0): #note: keywords are used directly
self.a = a
self.b = b

最新更新