Is it possible to initialize the argument of a method with a self.variable value from __init__ in python?

ぃ、小莉子 提交于 2021-02-05 08:25:10

问题


I have a class with an __init__ method where I define some variables, as well as a method AddSignalSpectrum:

class SpectrumGraph:
    
    # Properties
    def __init__(self):
        self.PlotHeight= 300 
        self.PlotWidth = 800 
        self.xRangeMin = -10 
        self.xRangeMax = 10
        self.yRangeMin = -0.1*(self.xRangeMax - self.xRangeMin)
        self.yRangeMax = 0.9*(self.xRangeMax -self.xRangeMin)

    def AddSignalSpectrum( 
        self,
        name,
        Type,
        CenterPosition,
        Bandwidth=2,
        Height = self.yRangeMax*0.8, 
        Color = "#0000FF", 
        LineWidth = 2,
        AbscissaSymbol = '$\omega_0$',
        ShowLegend = False):
     # Rest of the method

What I want is to provide the default value of self.yRangeMax*0.8 to the method but when I do that I get an error saying that 'self' is not defined. I can use attributes of self inside the method just fine, but it does not seem to work within the arguments of the method definition. I assume this is some sort of name space problem but can't find a workaround. It could be I'm just not sure what exactly to search for.


回答1:


This is not initialization, it is setting defaults for function parameters. The problem isn't to do with namespaces, it's to do with binding.

These values are determined once, ahead of time and are stored as part of the function (or method) object. It is not possible to use attributes of the self parameter here because there isn't one at the time that this happens. It is the same thing with ordinary functions:

def example(a, b=a+3): # doesn't work; `a` is not defined ahead of time
    print(f'a={a} and b={b}')

The normal workaround for this is to use None as the default value, and then explicitly check for this in the logic and replace None with the desired calculation:

def example(a, b=None): # works
    if b is None:
        b = a + 3
    print(f'a={a} and b={b}')

# and now we can call:
example(1) # 'a=1 and b=4'



回答2:


The usual way to do this is to set a sentinel value (idiomatically None) and then define behavior inside the method, e.g.:

def Dog:
    def __init__(self, name, friend):
        self.name = name
        self.friend = friend

    def say_hello(self, other=None):
        if other is None:
            other = self.friend

        print(f"Hello {other}, I'm {self.name}! How are you? Bark!")


来源:https://stackoverflow.com/questions/63095726/is-it-possible-to-initialize-the-argument-of-a-method-with-a-self-variable-value

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!