getattr和getattribute,getAttr

http://www.itjxue.com  2023-01-07 06:53  来源:未知  点击次数: 

Python中处理属性的重要属性和函数是什么

处理属性的重要属性和函数

1、特殊属性

__class__:对象所属类的引用(即obj.__class__和type(obj)的作用相同)。Python中的某些特殊方法比如 __getattr__,只在对象的类中寻找,而不在实例中寻找。__dict__:一个映射,存储对象或类的可写属性。__slots__:类可以定义这个属性,限制实例有哪些属性。

2、内置函数

dir([object]):列出对象的大多数属性。getattr(object,name[,default]):从object对象中获取name字符串对应的属性。获取的属性可能来自对象所属的类或超类。hasattr(object,name):若object对象中存在指定的属性,或者能以某种方式(如继承)通过object对象获取指定的属性,返回True。setattr(object,name,value):把object对象指定属性的值设为value,前提是object对象能接受那个值。这个函数可能会创建一个新属性,或者覆盖现有的属性。var([object]):返回object对象的__dict__属性。

相关推荐:《Python视频教程》

3、特殊方法

__delattr__(self,name):只要使用del语句删除属性,就会调用这个方法。__dir__(self):把对象传给dir函数时调用,列出属性。__getattr__(self,name):仅当获取指定的属性失败,搜索过obj,Class和超类之后调用。__getattribute__(self,name):尝试获取指定的属性时总会调用这个方法。不过寻找的属性是特殊属性或特殊方法时除外。为了防止无限递归,__getattribute__方法的实现要使用super().__getattribute__(obj,name)。__setattr__(self,name,value):尝试设置指定的属性时总会调用这个方法。点号和setattr内置函数会触发这个方法。

相关推荐:

Python中的属性和特性是什么

python 对象属性名称与关键字冲突怎么办?

可以通过getattr函数来获取和设置这样的属性

但是如果手上有源码的话

最好是进行修改

比如追加下划线来避免这种情况出现

python getattribute、get、getattr、getitem等用法

__getattribute__

__getattribute__是属性访问拦截器,就是当类的属性被访问时,会自动调用类的__getattribute__方法。

参考代码:

代码执行过程中,当调用实例对象attribute的name属性时,不会直接打印,而是把name的值作为实参传进__getattribute__方法中,经过一系列操作后,再把name的值返回。

python中只要定义了继承object的类,就默认存在属性拦截器,只不过是拦截后没有进行任何操作,而是直接返回。

我们可以自己改写__getattribute__方法来实现相关功能,比如查看权限、打印log日志等。

getattr、hasattr、setattr

对象属性的判断。

参考代码:

__getattr__、__setattr__、__delattr__

类支持 . 操作来访问属性;定制功能:耗时、日志等等。

参考代码:

__getitem__、__setitem__、__delitem__

类支持通过[]来访问属性

参考代码:

__get__、__set__、__delete__

参考代码:

参考文档:

python中的__getattr__问题

关于python的内置方法,希望能用一个简单的例子帮到你:

=========test.py

class a(object):

name = "Jim"

def __setattr__(self,name,value):

self.__dict__[name] = value

def __getattr__(self,name):

return name

b = a()

print dir(b)

print b.__dict__

print b.name

print b.notexists

print

b.name = "change"

print dir(b)

print b.__dict__

print b.name

print b.notexists

===========运行结果========

%python test.py

['__class__', '__delattr__', '__dict__', '__doc__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'name']

{}

Jim

notexists

['__class__', '__delattr__', '__dict__', '__doc__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'name']

{'name': 'change'}

change

notexists

============================

可以看到刚开始的时候b的__dict__对象里面是空的没有东西,当我们使用b.name访问的时候直接访问到的之前定义好的name属性:"Jim"

当我们使用b.name = "change"后就默认调用了内置方法__setattr__,此时我并没有直接操作self.name属性,而是直接在修改了self.__dict__['name'] = 'change'.之后当我再用b.name访问的时候获得的就是__dict__中的name属性的值。

于是我们可以看到__getattr__方法首先是在__dict__中找属性名,然后在实例的属性中找 ,然后再调用__getattr__方法获得值。

希望能帮到你

python类的属性有哪几种?如何访问它们?

属性的访问机制

一般情况下,属性访问的默认行为是从对象的字典中获取,并当获取不到时会沿着一定的查找链进行查找。例如?a.x?的查找链就是,从?a.__dict__['x']?,然后是?type(a).__dict__['x']?,再通过?type(a)?的基类开始查找。

若查找链都获取不到属性,则抛出?AttributeError?异常。

一、__getattr__?方法

这个方法是当对象的属性不存在是调用。如果通过正常的机制能找到对象属性的话,不会调用?__getattr__?方法。

class?A:

a?=?1

def?__getattr__(self,?item):

print('__getattr__?call')

return?item

t?=?A()

print(t.a)

print(t.b)

#?output

1

__getattr__?call

b

二、__getattribute__?方法

这个方法会被无条件调用。不管属性存不存在。如果类中还定义了?__getattr__?,则不会调用?__getattr__()方法,除非在?__getattribute__?方法中显示调用__getattr__()?或者抛出了?AttributeError?。

class?A:

a?=?1

def?__getattribute__(self,?item):

print('__getattribute__?call')

raise?AttributeError

def?__getattr__(self,?item):

print('__getattr__?call')

return?item

t?=?A()

print(t.a)

print(t.b)

所以一般情况下,为了保留?__getattr__?的作用,__getattribute__()?方法中一般返回父类的同名方法:

def?__getattribute__(self,?item):

return?object.__getattribute__(self,?item)

使用基类的方法来获取属性能避免在方法中出现无限递归的情况。

三、__get__?方法

这个方法比较简单说明,它与前面的关系不大。

如果一个类中定义了?__get__(),?__set__()?或?__delete__()?中的任何方法。则这个类的对象称为描述符。

class?Descri(object):

def?__get__(self,?obj,?type=None):

print("call?get")

def?__set__(self,?obj,?value):

print("call?set")

class?A(object):

x?=?Descri()

a?=?A()

a.__dict__['x']?=?1??#?不会调用?__get__

a.x??????????????????#?调用?__get__

如果查找的属性是在描述符对象中,则这个描述符会覆盖上文说的属性访问机制,体现在查找链的不同,而这个行文也会因为调用的不同而稍有不一样:

如果调用是对象实例(题目中的调用方式),a.x?则转换为调用:。type(a).__dict__['x'].__get__(a, type(a))

如果调用的是类属性,?A.x?则转换为:A.__dict__['x'].__get__(None, A)

其他情况见文末参考资料的文档

四、__getitem__?方法

这个调用也属于无条件调用,这点与?__getattribute__?一致。区别在于?__getitem__?让类实例允许?[]?运算,可以这样理解:

__getattribute__适用于所有.运算符;

__getitem__适用于所有?[]?运算符。

class?A(object):

????a?=?1

????def?__getitem__(self,?item):

????????print('__getitem__?call')

????????return?item

t?=?A()

print(t['a'])

print(t['b'])

如果仅仅想要对象能够通过?[]?获取对象属性可以简单的:

def?__getitem(self,?item):

????return?object.__getattribute__(self,?item)

总结

当这几个方法同时出现可能就会扰乱你了。我在网上看到一份示例还不错,稍微改了下:

class?C(object):

????a?=?'abc'

????def?__getattribute__(self,?*args,?**kwargs):

????????print("__getattribute__()?is?called")

????????return?object.__getattribute__(self,?*args,?**kwargs)

????#????????return?"haha"

????def?__getattr__(self,?name):

????????print("__getattr__()?is?called?")

????????return?name?+?"?from?getattr"

????def?__get__(self,?instance,?owner):

????????print("__get__()?is?called",?instance,?owner)

????????return?self

????def?__getitem__(self,?item):

????????print('__getitem__?call')

????????return?object.__getattribute__(self,?item)

????def?foo(self,?x):

????????print(x)

class?C2(object):

????d?=?C()

if?__name__?==?'__main__':

????c?=?C()

????c2?=?C2()

????print(c.a)

????print(c.zzzzzzzz)

????c2.d

????print(c2.d.a)

????print(c['a'])

可以结合输出慢慢理解,这里还没涉及继承关系呢。总之,每个以?__get?为前缀的方法都是获取对象内部数据的钩子,名称不一样,用途也存在较大的差异,只有在实践中理解它们,才能真正掌握它们的用法。

(责任编辑:IT教学网)

更多

相关JSP教程文章

推荐JSP教程文章