对比中和 获取属性的用法
更新日期:二〇一六年六月二十一日 十六点三十七分五十七秒,发布者:
本文重点阐述了在对比操作中如何获取属性,并强调了二者之间的差异性,特别指出这种操作仅适用于尚未存在的属性,有需要的朋友不妨查阅。
多数情况下,大家可能觉得我们无需过分关注那些琐碎的细节(至少对我来说是这样的:)))。
通常在使用我们自行定义的类别时,我们对其构造有充分的认知,因而不会有意偏离其结构,从而避免出现对属性访问的错误。
然而,鉴于我天生好奇、追求卓越且颇具气质,又怎能不对此略作探究呢?说到底,是阅读了一篇关于开源项目源码的文章后,我才开始关注的。那些代码颇为有趣,便借此机会,将其作为实际应用的范例,探究如何通过自定义手段使代码变得更加灵活和优雅。
对项目进行简化处理,剔除不必要的依赖和干扰因素,具体细节请参考原始项目资料。
class UrlGenerator(object):
def __init__(self, root_url):
self.url = root_url
def __getattr__(self, item):
若项目等于“获取”或项目等于“提交”。
print self.url
生成URL,格式为“{}{}”,其中第一个{}包含self.url,第二个{}包含item。
创建了一个名为url_gen的实例,该实例通过使用'http://xxxx'作为参数,调用了UrlGenerator类。
url_gen.users.show.get
>>> http://xxxx/users/show
充分利用其未找到对应实例属性时自动触发调用的特性,便捷地通过连续调用构建相应的网址,在源代码遇到HTTP标识时,将自动返回一个
可调用的对象愈发显得得体,链式操作不仅显得优雅,而且还能有效地阐释调用接口的内涵(也就是接口本身的意义)。
示例
1.示例:
class Test(object):
def __init__(self,name):
self.name = name
def __getattr__(self, value):
if value == 'address':
return 'China'
if __name__=="__main__":
test = Test('letian')
print test.name
print test.address
test.address = 'Anhui'
print test.address
运行结果:
letian China Anhui
若在某个类中调用了未被定义的方法,则应当提供一个方法作为回应,比如:
class Test(object):
def __init__(self,name):
self.name = name
def __getattr__(self, value):
return len
if __name__=="__main__":
test = Test('letian')
执行命令以获取'test'对象中'letian'字符串的长度。
运行结果:
2.示例:
class Test(object):
def __init__(self,name):
self.name = name
定义一个名为`__getattribute__`的方法,此方法接受两个参数,分别为`self`和`value`。
if value == 'address':
return 'China'
if __name__=="__main__":
test = Test('letian')
print test.name
print test.address
test.address = 'Anhui'
print test.address
运行结果:
None China China
深入思考
既然我们能够借助定制化的自定义方法来达成某些精致的功能,那么我们理应深入掌握其相关知识,这包括对其相似的自定义方法的理解。
1. 用作实例属性的获取和拦截
在访问特定实例的属性时,系统会自动执行相应的操作;若未定义相应的方法,则会触发一个错误信息,指出该属性未找到;相反,若已定义了对应的方法,那么在遇到属性缺失的情况下,该方法将被执行,正如前述示例所展示的情形。在无法直接获取属性值时,采用自定义的解决方案来达成某些功能不失为一个好办法,这样做可以避免每次调用方法时都可能干扰到常规属性的使用。
class Test(object):
def __init__(self, p):
self.p = p
def __getattr__(self, item):
return 'default'
t = Test('p1')
print t.p
print t.p2
>>> p1
>>> default
2. 自定义的时候防止无限递归
在访问属性的过程中,该方法会不断被触发,而在自定义的方法中,又必须输出相应的属性值。使用self关键字进行赋值时,会引发连续的调用,进而形成循环引用。
class AboutAttr(object):
def __init__(self, name):
self.name = name
在执行获取属性的操作时,该函数被调用来处理,参数self代表当前对象,item表示要获取的属性名称。
try:
调用父类AboutAttr的self实例,并使用其__getattribute__方法来获取指定项的值。
except KeyError:
return 'default'
此处,我们通过引用已连接的super对象来取得队形的相关信息,对于新式类而言,这实际上等同于直接使用(self, item)的方式进行操作。
在默认设置下,用户定义的类能够继承并使用继承自其他类的方法,同时对属性的检索功能同样有效。
实现的过程给人的感觉较为抽象,但只需将对应的实例对象与所需查询的属性名称进行关联即可。
在执行覆盖操作并切换至相应状态时,需按照原样重现原有行为,通过模拟或手动触发来实现。
class AboutAttr(object):
def __init__(self, name):
self.name = name
def __getattribute__(self, item):
try:
return super(AboutAttr, self).__getattribute__(item)
except KeyError:
return 'default'
except AttributeError as ex:
print ex
def __getattr__(self, item):
return 'default'
at = AboutAttr('test')
print at.name
print at.not_exised
>>>test
关于'AboutAttr'的对象,并不存在名为'not_exised'的属性。
>>>None
在上述例子中,该方法根本未被激活,这主要是因为我们已自行处理了相关内容,既未引发异常,亦未手动执行调用,因此,访问结果呈现为空值而非其他。
扫一扫在手机端查看
-
Tags : Python getattr getattribute
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。


客服1