Python自定义IO类中__getattribute__与__getattr__属性查找异常咨询
自定义IO类属性查找异常分析
自定义代码
import io class Test(io.BufferedIOBase): def __init__(self, f): self.f = f def __getattr__(self, name): print("getattr: searching for: ", name) #try: # v = getattr(self.f, name) #except Exception: # print(" found nothing!") # raise #print(" found: ", v) #return v #return 22 raise AttributeError(name) def __getattribute__(self, name): print("1.getattribute@self: searching for: ", name, flush=True) try: v = super().__getattribute__(name) except Exception as e: print(" 1.exception: ", e) print(" 1.found nothing!", flush=True) pass else: print(" 1.found: ", v, flush=True) return v print("2.getattribute@self.f: searching for: ", name, flush=True) #f = super().__getattribute__("f") f = object.__getattribute__(self, "f") try: v = getattr(f, name) except Exception as e: print(" 2.exception: ", e) print(" 2.found nothing!", flush=True) raise else: print(" 2.found: ", v, flush=True) return v print("ERROR") p = "test_file.bin" # 假设存在该测试文件 f1 = open(p, "rb") f2 = Test(f1) print("\nTest 01:") v = f2.closed print("result: ", v) print("\nTest 02:") v = f2.qwer print("result: ", v)
运行结果
Test 01: 1.getattribute@self: searching for: closed 1.getattribute@self: searching for: __IOBase_closed 1.exception: 'Test' object has no attribute '__IOBase_closed' 1.found nothing! 2.getattribute@self.f: searching for: __IOBase_closed 2.exception: '_io.BufferedReader' object has no attribute '__IOBase_closed' 2.found nothing! getattr: searching for: __IOBase_closed 1.found: False result: False Test 02: 1.getattribute@self: searching for: qwer 1.exception: 'Test' object has no attribute 'qwer' 1.found nothing! 2.getattribute@self.f: searching for: qwer 2.exception: '_io.BufferedReader' object has no attribute 'qwer' 2.found nothing! getattr: searching for: qwer --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[532], line 49 47 print("result: ", v) 48 print("\nTest 02:") ---> 49 v = f2.qwer 50 print("result: ", v) Cell In[532], line 15, in Test.__getattr__(self, name) 6 print("getattr: searching for: ", name) 7 #try: 8 # v = getattr(self.f, name) 9 #except Exception: (...) 13 #return v 14 #return 22 ---> 15 raise AttributeError(name) AttributeError: qwer
用户分析与疑问
根据object.__getattribute__()文档,梳理属性查找流程如下:
closed是IOBase中的非数据属性。- 访问该属性时,会在
__getattribute__返回前触发内部逻辑,查找self.__closed;按照Python名称修饰规则,这个属性实际应为_IOBase__closed。
实际运行中出现两个异常点:
- 自定义
__getattribute__的日志显示,程序在查找不存在的__IOBase_closed而非正确的_IOBase__closed,推测是Python与CPython的实现差异导致。 - 自定义的
__getattribute__和__getattr__均抛出了AttributeError,但最终却成功返回了_IOBase__closed的值,猜测Python调用了MRO中更高层级的属性查找函数,但对这一逻辑存在困惑,希望得到解答。
内容的提问来源于stack exchange,提问作者user19087
相关产品推荐
相关产品推荐

