[python]三方库bs4(BeautifulSoup)的对象可以使用任何名字作为属性是怎么实现的?
举例:
from bs4 import BeautifulSoupfp = open('test.html', encoding='utf-8')
soup = BeautifulSoup(fp, 'lxml')
soup.a # 1
soup.script # 2
soup.div # 3
soup.abcdefg # 4
说明:
soup实例可以使用标签名作为属性,返回封装了test.html中正序第一个该标签内容的bs4.element.Tag对象。
但是我发现属性a、script、div并没有事先定义在类中,并且即便是随便输入的属性名(#4)也不会抛出异常,只是返回一个None。
在我的认知中,对象的属性是需要事先在类中定义、或者动态绑定的,像bs4这样可以直接的使用任意属性名,是怎么实现的?
回答:
在Python 类里,只要实现以下方法:
__getattr__(self, name)
__setattr__(self, name, value)
__delattr__(self, name)
便可以动态使用属性
请参阅http://docs.python.org/reference/datamodel.html#customizing-attribute-access
__getattr__
方法可能如下所示:
def __getattr__(self, name): try:
return self.__dict[name]
except KeyError:
msg = "'{0}' object has no attribute '{1}'"
raise AttributeError(msg.format(type(self).__name__, name))
一个小例子:
class ObjectDict(dict): def __init__(self, *args, **kwargs):
super(ObjectDict, self).__init__(*args, **kwargs)
def __getattr__(self, name):
try:
value = self[name]
if isinstance(value, dict):
value = ObjectDict(value)
return value
except KeyError:
return None
if __name__ == '__main__':
od = ObjectDict(asf={'a': 1}, d=True)
print(od.asf, od.asf.a) # {'a': 1} 1
print(od.d) # True
print(od.x) # None
以上是 [python]三方库bs4(BeautifulSoup)的对象可以使用任何名字作为属性是怎么实现的? 的全部内容, 来源链接: utcz.com/a/164360.html