如果要获得一个对象的所有属性和方法,可以使用dir()
函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:
>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']
类似
__xxx__
的属性和方法在Python中都是有特殊用途的比如
__len__
方法返回长度。在Python中,如果你调用len()
函数试图获取一个对象的长度,实际上,在len()
函数内部,它自动去调用该对象的__len__()
方法,同时,也可以显式调用,对象.__len__()
。很多函数如__XX__()形式,不一定可以 XX(实例)的形式调用。
比如:
1、对象.__doc__ 不可以使用doc(对象)
2、getattr(insA,'grade')与insA.grade一样,与 __getattr__()方法则不同。
3、__getitem__()的使用方法其实是: dataset[0]
所以,下面的代码是等价的:
>>> len('ABC')
#3
>>> 'ABC'.__len__()
#3
>>> dir('ABC')
#['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']
>>> 'ABC'.__dir__()
#['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']
>>> 'ABC'.__sizeof__()
# 52
>>>sizeof('ABC')
'''错误'''
#NameError: name 'sizeof' is not defined
我们自己写的类,如果也想用len(myobj)
的话,就自己写一个__len__()
方法:
>>> class MyDog(object):
... def __len__(self):
... return 100
...
>>> dog = MyDog()
>>> len(dog)
100
剩下的都是普通属性或方法,比如lower()
返回小写的字符串:
>>> 'ABC'.lower()
'abc'
仅把属性和方法列出来是不够的,配合
getattr()
、setattr()
以及hasattr()
我们可以直接操作一个对象的状态:
>>> class MyObject(object):
... def __init__(self):
... self.x = 9
... def power(self):
... return self.x * self.x
...
>>> obj = MyObject()
>>> hasattr(obj, 'x') # 有属性'x'吗?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有属性'y'吗?
False
>>> setattr(obj, 'y', 19) # 设置一个属性'y'
>>> hasattr(obj, 'y') # 有属性'y'吗?
True
>>> getattr(obj, 'y') # 获取属性'y'
19
>>> obj.y # 获取属性'y'
19
如果试图获取不存在的属性,会抛出AttributeError的错误:
>>> getattr(obj, 'z') # 获取属性'z'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'MyObject' object has no attribute 'z'
可以传入一个default参数,如果属性不存在,就返回默认值:
>>> getattr(obj, 'z', 404) # 获取属性'z',如果不存在,返回默认值404
404
所以说getattr()与类的__getattr__()方法就不一样
如下例:insA.grade和 getattr(insA,'grade') 调用属性的方式是一样的,如果要查询的属性不在__dict__中,则转向__getattr__()方法。
当然也可以显式调用__getattr__()方法,但这样的话无论属性是否在__dict__中,都调用了__getattr__()。
class ClassA(object):
def __init__(self, classname):
self.classname = classname
insA = ClassA('ClassAname')
print(insA.__dict__) # 实例insA已经有classname属性了
# {'classname': 'ClassAname'}
print(insA.classname)
# ClassAname
print(getattr(insA,'classAname'))
# ClassAname
print(insA.grade)
#'ClassA' object has no attribute 'grade'
print(getattr(insA,'grade'))
#AttributeError: 'ClassA' object has no attribute 'grade'
print(insA.__getattr__('grade'))
'''错误,因为没有__getattr__方法'''
#'ClassA' object has no attribute '__getattr__'
print(getattr(insA,'grade',23))
'''有默认值则可以'''
#23
class ClassA(object):
def __init__(self, classname):
self.classname = classname
def __getattr__(self, attr):
return('invoke __getattr__', attr)
insA = ClassA('ClassAname')
print(insA.classname)
#ClassAname
print(getattr(insA,'classname'))
#ClassAname
print(insA.__getattr__('classname'))
#('invoke __getattr__', 'classname')
也可以获得对象的方法:
obj.power 与 getattr(obj, 'power')是相同的,是函数的地址
obj.power() 与 getattr(obj,'power')()是相同的
>>> class MyObject(object):
... def __init__(self):
... self.x = 9
... def power(self):
... return self.x * self.x
...
>>> obj = MyObject()
>>> hasattr(obj, 'power') # 有属性'power'吗?
True
>>> getattr(obj, 'power') # 获取属性'power'
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn
>>> fn # fn指向obj.power
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn() # 调用fn()与调用obj.power()是一样的
81
class ClassA(object):
def __init__(self, classname):
self.classname = classname
def power(self, attr):
return('power:', attr*2)
insA = ClassA('ClassAname')
print(insA.__dict__) # 实例insA已经有classname属性了
# {'classname': 'ClassAname'}
print(insA.classname)
# ClassAname
'''下面两种方法一样的,都是返回方法的地址'''
print(getattr(insA,'power'))
#<bound method ClassA.power of <__main__.ClassA object at 0x000001DDCBA466A0>>
print(insA.power)
#<bound method ClassA.power of <__main__.ClassA object at 0x000001DDCBA466A0>>
'''*****************************************************'''
'''下面两种方法一样的'''
print(getattr(insA,'power')(2))
#('power:', 4)
print(insA.power(2))
#('power:', 4)