ahqianjin1949 发表于 2024-6-13 13:02:52

类装饰器问题

https://xxx.ilovefishc.com/forum/202406/13/125915m33v7vv0eq8kgoxs.png

大神的python视频教程中类装饰器这期,访问类不存在的属性出现死循环啊,是否属于python版本有问题吗?求解答哈?

Twilight6 发表于 2024-6-13 13:02:53


因为你 Check 的 __init__ 中赋值的是 self.cls,即被装饰的类的实例赋值给了 self.cls,而不是 self.obj

从你代码中看 self.obj 对于这个对象是不存在的

那么当你 __getattr__ 访问属性被调用时,返回的 getattr 传入的是 self 不存在的属性,那么他就会递归调用 self 本身的 __getattr__

想要避免这种问题,你需要将 self.obj 对象指定,且不应该是 Check 的实例

其实只需要将你的 self.cls 改成 self.obj 即可

FishC 发表于 2024-6-13 13:03:07

可能不是Python版本的问题,而是代码中的逻辑错误导致了死循环。

在类装饰器中,当你访问一个类不存在的属性时,会触发 `__getattr__` 方法。在这个方法内部,你可以选择处理这个属性的获取操作,或者将它委托给原始类处理。如果你选择委托给原始类来处理,但是原始类又没有相应的属性,又会触发 `__getattr__` 方法,这样就会导致无限递归调用,形成死循环。

解决这个问题的方法是,在 `__getattr__` 方法中判断是否存在相应的属性,如果不存在,则抛出 `AttributeError` 异常或返回一个默认值,而不委托给原始类处理。下面是一个示例代码:

class Decorator:
    def __init__(self, original_class):
      self.original_class = original_class

    def __getattr__(self, item):
      if hasattr(self.original_class, item):
            return getattr(self.original_class, item)
      else:
            raise AttributeError(f"'{self.original_class.__name__}' object has no attribute '{item}'")
      
@Decorator
class MyClass:
    def __init__(self):
      self.name = "FishC"

my_object = MyClass()
print(my_object.name)# 输出 FishC
print(my_object.age)   # 抛出 AttributeError 异常

在上面的代码中,我们在 `__getattr__` 方法中先判断原始类是否具有所需要的属性,如果有就返回属性值,如果没有就抛出异常。这样就避免了死循环的问题。

希望能帮到你!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

ahqianjin1949 发表于 2024-6-14 05:11:03

Twilight6 发表于 2024-6-13 13:02
因为你 Check 的 __init__ 中赋值的是 self.cls,即被装饰的类的实例赋值给了 self.cls,而不是 self.obj ...

多谢了,已经解决{:5_110:}
页: [1]
查看完整版本: 类装饰器问题