为什么我的Class成员变量在Python中丢失了?

时间:2017-09-09 15:34:38

标签: python python-3.x class methods member-variables

我上了课。我认为我在初始化器/构造函数中创建了一个名为“myTup”的成员变量。我尝试通过在初始化程序的最后进行以下调用来确保我确实创建了myTup:

a

但是,稍后,解释器说我的实例/对象没有名为“myTup”的成员变量。

myTup在哪里?回到我身边......请Q_Q

由于所有的小调试语句,以下脚本只有很长时间。没有调试,它实际上非常简短。

代码:

assert(hasattr(self, 'myTup'))

输出:

import inspect
def lineno():
    # Returns the current line number in our program.
    return inspect.currentframe().f_back.f_lineno

class DemoClass:

    def __init__(self, initial_data):

        went_in = False # did not enter the if-elif-else block

        if isinstance(initial_data, str):
            print('line number:', lineno())
            t = tuple(initial_data)
            self = DemoClass(t)
            went_in = True        
        elif isinstance(initial_data, DemoClass):
            print('line number:', lineno())
            self = initial_data
            went_in = True
        elif isinstance(initial_data, tuple):
            print('line number:', lineno())
            self.myTup = initial_data
            went_in = True
        else:
            print('line number:', lineno())
            went_in = True
            assert(False)

        assert(hasattr(self, 'myTup'))
        print('line number:', lineno())
        print('went_in:', went_in)
        print('myTup:', self.myTup)

    def __str__(self):
        return "DemoClass" + str(self.myTup)

obj = DemoClass("s")
print(obj)

1 个答案:

答案 0 :(得分:3)

您无法替换__init__中创建的实例。以下内容仅替换self方法中的__init__引用,不是self绑定到的上一个实例:

if isinstance(initial_data, str):
    # ...
    t = tuple(initial_data)
    self = DemoClass(t)

__init__返回时,obj = DemoClass("s")行仍然绑定第一个实例,而不是您使用递归调用创建的实例。第一个实例没有myTup属性。

您必须致电self.__init__(t)而不是在同一个实例上操作:

if isinstance(initial_data, str):
    # ...
    t = tuple(initial_data)
    self.__init__(t)

然后再次调用__init__,绑定相同的实例,从而在正确的对象上设置myTup

请注意,我在这里避免使用递归。没有必要,只需在不同的分支中设置一个元组,然后在最后分配myTup

def __init__(self, initial_data):
    if isinstance(initial_data, str):
        initial_data = tuple(initial_data)
    elif isinstance(initial_data, DemoClass):
        initial_data = initial_data.myTup
    elif not isinstance(initial_data, tuple):
        raise ValueError('Invalid data')

    self.myTup = initial_data

如果您在尝试使用DemoClass()创建新实例时必须控制返回的实例,那么您只能使用__new__ method执行此操作;它负责首先生成实例(之后默认实现将在该新实例上调用__init__)。