3

您好,我有一个关于 Python 中属性使用的问题。我了解到,在函数定义中,我们可以为对象分配一些新属性,例如:self!但是,当尝试使用它时,我得到了一个错误,即“......实例没有属性'数据'

class Lazy:
    def __call__(self, num):
            if num is None:
                    return self.data
            # It changes the current object in-place,
            # by reassigning the self attribute.
            else:
                    self.data += num

这是我的小代码。我对此很陌生。我不知道出了什么问题。非常感谢你。

4

5 回答 5

4

您只是在分配self.dataif num is None,因此您可能会在分配之前尝试访问它。为了防止这种情况,您可以在构造函数中对其进行初始化:

class Lazy:
    def __init__(self):
        self.data = 0

    def __call__(self, num):
        if num is None:
            return self.data
        else:
            self.data += num

以下是导致您的错误的事件顺序:

  1. 你创建了你的类的一个新实例。在这一点上,Python 一无所知self.data

    lazy = Lazy()
    
  2. 你称之为传递None

    lazy(None)
    
  3. 现在,Python 进入__call__,并且因为 if 条件计算结果为True它尝试返回self.data。等一下……它仍然不知道是什么self.data……所以它吐出了一个错误。

为了防止这种情况,您总是必须在尝试使用它们的值做某事之前分配您的属性(例如,从函数中返回它们)。它不必在构造函数中:就在 Python 第一次尝试访问该属性之前。对于任何变量都是如此,即以下是不可能的:

print(a) # How do you expect Python to know the value of a?
a = 5    # too late to assign it now...
于 2013-04-07T15:03:54.290 回答
1

您正在尝试引用self.data但未初始化/声明它。

class Lazy:
    def __init__(self, data=0):
        self.data = data #You are initializing data to 0 or a user specified value

    def __call__(self, num):
        if num is None:
            return self.data
            # It changes the current object in-place,
            # by reassigning the self attribute.
        else:
            self.data += num
于 2013-04-07T15:05:25.903 回答
1

为了修改self.data,您必须首先使用类的特殊方法初始化self.data属性。__init__

来自官方文档:

object.__init__(self[, ...])

创建实例时调用。参数是传递给类构造函数表达式的参数。

所以你可以设置self.data为 0,那么你的__call__方法应该像写的那样工作。

class Lazy:
    def __init__(self):
        self.data = 0

    def __call__(self, num):
        if num is None:
            return self.data
        else:
            self.data += num
于 2013-04-07T15:07:11.353 回答
1

您可以在方法中或其他任何地方初始化属性__init__()(尽管__init__()是推荐的地方)。

self.data如果它不存在,请尝试初始化它。

class Lazy:
    def __call__(self, num):
            try:
                self.data
            except:
                self.data = 0
            if num is None:
                    return self.data
            # It changes the current object in-place,
            # by reassigning the self attribute.
            else:
                    self.data += num

我希望它有所帮助。

于 2013-04-07T15:26:04.700 回答
1

我想在您的代码中指出:

class Lazy:
def __init__(self):
    self.data = 0

def __call__(self, num):
    if num is None:
        return self.data

假设如果你调用你的实例:lazy(some_value)那么你的 else 分支将执行,其计算结果为:

    else:
        self.data += num # self.data = self.data + num

但是,可能存在 self.data 在这种情况下可能未定义的情况,它也会通过上述错误。

我同意上述所有答案,但我也需要关注这个极端案例。

请享用!

于 2013-04-07T15:38:17.557 回答