鱼C论坛

 找回密码
 立即注册
查看: 269|回复: 3

[已解决]类装饰器问题

[复制链接]
发表于 2024-6-13 13:02:52 | 显示全部楼层 |阅读模式
20鱼币

                               
登录/注册后可看大图


大神的python视频教程中类装饰器这期,访问类不存在的属性出现死循环啊,是否属于python版本有问题吗?求解答哈?
最佳答案
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 即可

最佳答案

查看完整内容

因为你 Check 的 __init__ 中赋值的是 self.cls,即被装饰的类的实例赋值给了 self.cls,而不是 self.obj 从你代码中看 self.obj 对于这个对象是不存在的 那么当你 __getattr__ 访问属性被调用时,返回的 getattr 传入的是 self 不存在的属性,那么他就会递归调用 self 本身的 __getattr__ 想要避免这种问题,你需要将 self.obj 对象指定,且不应该是 Check 的实例 其实只需要将你的 self.cls 改成 self.obj 即可 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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 即可

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-6-14 05:11:03 | 显示全部楼层
Twilight6 发表于 2024-6-13 13:02
因为你 Check 的 __init__ 中赋值的是 self.cls,即被装饰的类的实例赋值给了 self.cls,而不是 self.obj ...

多谢了,已经解决
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-15 20:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表