Function's attributes when in a class

╄→尐↘猪︶ㄣ 提交于 2021-02-11 13:09:31

问题


I can use a function's attribute to set a status flag, such as

def Say_Hello():
    if Say_Hello.yet == True:
        print('I said hello already ...')
    elif Say_Hello.yet == False:
        Say_Hello.yet = True
        print('Hello!')

Say_Hello.yet = False

if __name__ == '__main__':
    Say_Hello()
    Say_Hello()

and the output is

Hello!
I said hello already ...

However, when trying to put the function in a class, like

class Speaker:
    def __init__(self):
        pass

    def Say_Hello(self):
        if self.Say_Hello.yet == True:
            print('I said hello already ...')
        elif self.Say_Hello.yet == False:
            self.Say_Hello.yet = True
            print('Hello!')

    Say_Hello.yet = False

if __name__ == '__main__':
    speaker = Speaker()
    speaker.Say_Hello()
    speaker.Say_Hello()

There is this error:

Traceback (most recent call last):

  File "...func_attribute_test_class_notworking.py", line 16, in <module>
     speaker.Say_Hello()
  File "...func_attribute_test_class_notworking.py", line 9, in Say_Hello
    self.Say_Hello.yet = True
AttributeError: 'method' object has no attribute 'yet'

What is the proper way to use function's attribute in a class?


回答1:


Speaker.Say_Hello and speaker.Say_Hello are two different objects. The former is the function defined in the body of the class statement:

>>> Speaker.Say_Hello
<function Speaker.Say_Hello at 0x1051e5550>

while the latter is an instance of method:

>>> speaker.Say_Hello
<bound method Speaker.Say_Hello of <__main__.Speaker object at 0x10516dd60>>

Further, even time you access speaker.Say_Hello, you get a different instance of method.

>>> speaker.Say_Hello is speaker.Say_Hello
False

You should just use self instead. Function attributes are more of an accidental feature that isn't specifically prohibited rather than something you should use, anyway.

class Speaker:
    def __init__(self):
        self._said_hello = False

    def Say_Hello(self):
        if self._said_hello:
            print('I said hello already ...')
        else:
            self._said_hello = True
            print('Hello!')

If you want to track if any instance of Speaker has called its Say_Hello method, rather than tracking this for each instance separately, use a class attribute.

class Speaker:
    _said_hello = False

    def Say_Hello(self):
        if self._said_hello:
            print('Someone said hello already ...')
        else:
            type(self)._said_hello = True
            print('Hello!')


来源:https://stackoverflow.com/questions/64991519/functions-attributes-when-in-a-class

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