是否可以从方法调用变量而不作为返回变量传递?

2024-06-07 17:32:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为不同生态系统中的一些鸟类种群参数编写一个库。为了不重复代码,我想获取在前面的方法中定义的一些变量,并在其他方法中使用这些变量,而不将此变量作为返回传递。比如说

class asd:
    
    def __init__(self): 
        self.a = a
        self.b = b

    def fun1(self):
        self.a2 = self.a * 2

    def fun2(self):
        self.a4 = self.a2*2 #this is what i want to do. 

Tags: 方法代码selfa2参数定义init鸟类
3条回答

不,这是不可能的,变量总是只存在于它们的作用域中。您需要使用全局变量来实现所需的功能,否则必须覆盖实例变量。这取决于您想要解决的问题和代码的设计

在不影响变量作用域的情况下实现这一点的一个好方法是使用sentinel值初始化self.a2,通常是None

然后您可以检查fun2()中的self.a2并做出相应的反应,即在表达式之前调用fun1()

class asd:
        
    def __init__(self): 
        self.a = a
        self.b = b
        self.a2 = None

    def fun1(self):
        self.a2 = self.a * 2

    def fun2(self):
        if self.a2 is None:
            self.fun1()
        self.a4 = self.a2*2

实际上,您还可以去掉sentinel变量,并使用hasattr()作为检查:

class asd:
    
    def __init__(self): 
        self.a = a
        self.b = b

    def fun1(self):
        self.a2 = self.a * 2

    def fun2(self):
        if not hasattr(self, "a2")
            self.fun1()
        self.a4 = self.a2*2

如果您的self.a2可以被分配任何值,包括None,这可能会很有用,从而破坏哨兵的目的。但事实并非如此,因为你在数学表达式中使用它

正如@ffm_nosoup所述,由于函数作用域的原因,这不可能按要求实现

完成这类工作的一般方法是在类本身中存储您想要的任何值,并引用这些值。假设fun1的结果计算成本很高,并且您不希望在可能的情况下重新计算,您的特定示例可能会改写为:

class Asd:
    def __init__(self): 
        self.a = a
        self.b = b
        self.a2 = None

    def fun1(self):
        self.a2 = self.a * 2

    def fun2(self):
        if self.a2 is None:
            raise ValueError("Attempted to use result from fun1() without first calling fun1()")
        self.a4 = self.a2 * 2

或者,您可以自动调用fun1,但在某些情况下,这可能是一种风险更大的设计选择

def fun2(self):
    if self.a2 is None:
        self.fun1()
    self.a4 = self.a2 * 2

第三种选择是只使用cache,它只会计算函数一次,并在将来重用该结果。(正如Mark Ransom在评论中指出的,如果您需要重新计算fun1的结果,这将导致问题。)

from functools import lru_cache

class Asd:
    def __init__(self): 
        self.a = a
        self.b = b

    @lru_cache
    def fun1(self):
        return self.a * 2

    def fun2(self):
        self.a4 = self.fun1() * 2

相关问题 更多 >

    热门问题