1

我正在尝试实现一个简单的模型类,只要在类中设置一个属性,它就会执行回调,但是当我尝试在我的应用程序中使用它时,我得到了一个 AttributeError 。似乎该实例没有我在初始化程序中设置的属性,我对为什么有点困惑。我没有太多使用魔术方法,所以一些详细说明可能会有所帮助:

class ReportModel(object):

    def __init__(self):
        self.current_date = None
        self.prior_date = None
        self._callbacks = defaultdict([])

    def __setattr__(self, attr, value):
        object.__setattr__(self, attr, value)
        for func in self._callbacks[attr]:
            func(value)

    def set_callback(self, attr, function):
        self._callbacks[attr].append(function)

追溯:

AttributeError: 'ReportModel' object has no attribute '_callbacks'
4

2 回答 2

2

您的__setattr__方法在类实例化期间被调用,当__init__正在运行和设置self.current_dateself.prior_date.

要解决此问题,您必须使用 try,除了阻止回调调用以防止错误。

    try:
        for func in self._callbacks[attr]:
            func(value)
    except:
        pass
于 2013-07-22T17:19:11.137 回答
2

由于您已经覆盖__setattr__(),当您这样做self.current_date = None__init__(),它将调用您的__setattr__()实现,该实现将尝试访问self._callbacks。这就是导致 AttributeError 的原因。

这是解决此问题的一种方法:

class ReportModel(object):

     def __init__(self):
         object.__setattr__(self, '_callbacks', defaultdict(list))
         self.current_date = None
         self.prior_date = None

     def __setattr__(self, attr, value):
         object.__setattr__(self, attr, value)
         for func in self._callbacks[attr]:
             func(value)

     def set_callback(self, attr, function):
         self._callbacks[attr].append(function)

这会在添加任何其他属性之前添加_callbacks属性 using object.__setattr__(),以便将来__setattr__()对您的ReportModel实例的调用不会在访问时阻塞self._callbacks

或者,您可以修改__setattr__()以检查_callbacks属性是否存在:

class ReportModel(object):

     def __init__(self):
         object.__setattr__(self, '_callbacks', defaultdict(list))
         self.current_date = None
         self.prior_date = None

     def __setattr__(self, attr, value):
         object.__setattr__(self, attr, value)
         if hasattr(self, '_callbacks'):
             for func in self._callbacks[attr]:
                 func(value)

     def set_callback(self, attr, function):
         self._callbacks[attr].append(function)
于 2013-07-22T17:20:07.487 回答