新手python继承问题..当你写下面的内容时:
sqlOutputAssetClass <- reactive({
sqlInputAssetClass<- paste("select distinct ASSET_CLASS from DUMMY_TABLE",sep="")
unname(dbGetQuery(con, sqlInputAssetClass))
})
产生
class A:
def foo(self):
print("a")
class B(A):
pass
b = B()
getattr(b, "foo")
看起来Python创建了一个绑定到<bound method A.foo of <__main__.B object at 0x000000000604CC88>>
的属性foo
,它知道A.foo
是foo
方法。
我是否应该将继承视为简单地创建指向基类对象的指针(并且解释器知道它是基类对象),而不是在派生类中创建属性的副本?
似乎这是一个重要的观点,但最初我不清楚 - 在玩A
时遇到了这个问题。
答案 0 :(得分:1)
你是部分正确的,让我们从你的错误开始。
我是否应该将继承视为简单地创建指向基类对象的指针
这是不正确的。当您使用obj.attr
或foo
访问属性时,Python会首先通过method resolution order恢复该属性。特别是这意味着不会在创建类时发生,而是在属性查找时发生。
看起来Python创建了一个绑定到
的属性A.foo
__get__
这是对的。绑定类或实例方法在进程中创建了一个新对象。
恢复属性后,Python可能需要绑定它。它首先检查它是否是descriptor,这是一个具有getattr
方法的对象,允许将其绑定到某个实例。
这是def _resolve_cls_attr(cls, attr):
if attr in cls.__dict__:
return cls.__dict__[attr]
elif len(cls.__mro__) > 1:
return _resolve_cls_attr(cls.__mro__[1], attr)
else:
raise AttributeError('class has no attribute {}'.format(attr))
的Python实现,可帮助您查看检索属性时发生的情况。
首先,这是Python使用 mro 解析类属性的方式。
getattr
然后,如果它是在Python中,这就是def getattr(instance, attr):
cls = instance if isinstance(instance, type) else type(instance)
# Recover instance attribute
if hasattr(instance, '__dict__') and attr in instance.__dict__:
attr_value = instance.__dict__[attr]
# Recover the attribute from the class
else:
attr_value = _resolve_cls_attr(cls, attr)
# We recovered a simple class attribute
if not hasattr(attr_value, '__get__'):
return attr_value
# We recovered an instance method from a class or a staticmethod descriptor
if instance is cls or isinstance(attr_value, staticmethod):
return attr_value.__get__(None, cls)
# We recovered an instance method or a custom descriptor
return attr_value.__get__(instance, cls)
的实现方式。
__getattr__
请注意,为了坚持您的问题,上面省略了几个步骤。例如,它不会依赖__getattribute__
和getattr
作为内置{{1}}。