自省反射
自省和反射是两个比较专业化的术语,释义如下:
- 自省是指获取对象的能力
- 反射是指操纵对象的能力
由于Python是一门强类型的动态解释型语言,所以它的自省和反射使用非常简单。
我们在某些时候并不知道对象中具有的属性与方法,尤其是接手别人的项目时这种情况更加明显。
在这种情况下,我们不能直接通过Object.__dict__来获取其对象的属性与方法(因为这样获取不到继承的属性),而应当先使用自省来获取对象信息后,再使用反射来操纵对象,故自省和反射的学习显得尤为重要。
以下举例常见自省与反射的函数:
函数 | 返回值 | 描述 |
---|---|---|
help(object) | None | 获取对象文档帮助信息 |
dir(object) | list | 获取对象下所有能被.操纵的属性与方法 |
hasattr(object, str) | bool | 返回对象是否具有给定名称的属性或方法 |
getattr(object, str, default) | attr | 获取对象中指定的属性或方法,若该属性或方法不存在,则抛出AttributeError异常,若设置默认值,则在属性或方法不存在时返回默认值 |
setattr(object, str, any) | None | 设置对象中某一属性或方法的值 |
delattr(object, str) | None | 删除对象中某一指定属性或方法 |
issubclass(subClass, parentClass) | bool | 判定一个类是否是另一个类的子类 |
isinstance(instance, class) | bool | 判定一个对象是否是另一个类的实例 |
callable(object) | bool | 判定该对象是否可调用 |
示例演示
help(object)能够获取对象文档帮助信息。
返回None:
>>> help(int)
Help on class int in module builtins:
class int(object)
| int(x=0) -> integer
| int(x, base=10) -> integer
|
| Convert a number or string to an integer, or return 0 if no arguments
| are given. If x is a number, return x.__int__(). For floating point
| numbers, this truncates towards zero.
|
| If x is not a number or if base is given, then x must be a string,
| bytes, or bytearray instance representing an integer literal in the
| given base. The literal can be preceded by '+' or '-' and be surrounded
...
dir(object)能够获取对象下所有能被.操纵的属性与方法。
返回list:
>>> dir(list)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
hasattr(object, str)能够返回对象是否具有给定名称的属性或方法。
返回bool:
>>> hasattr(list, "index")
True
>>> hasattr(list, "items")
False
getattr(object, str, default)能够获取对象中指定的属性或方法,若该属性或方法不存在,则抛出AttributeError异常,若设置默认值,则在属性或方法不存在时返回默认值:
>>> method = getattr(list, "index")
>>> method
<method 'index' of 'list' objects>
>>> method([1, 2, 3], 2)
1
setattr(object, str, any)能够设置对象中某一属性或方法的值。
返回None:
>>> class A:
... pass
...
>>> A.__doc__
None
>>> setattr(A, "__doc__", "help message")
>>> A.__doc__
help message
delattr(object, str)能够删除对象中某一指定属性或方法。
返回None:
>>> class A:
... classAttr = "attr"
...
>>> A.classAttr
'attr'
>>> delattr(A, "classAttr")
>>> A.classAttr
AttributeError: type object 'A' has no attribute 'classAttr'
issubclass(subClass, parentClass)可以判定一个类是否是另一个类的子类。
返回bool:
>>> issubclass(bool, int)
True
isinstance(instance, class)可以判定一个对象是否是另一个类的实例。
返回bool:
>>> isinstance(1, bool)
False
>>> isinstance(True, bool)
True
常用操作
当不确定对象中是否具有某一属性或方法时,可以使用hasattr(),getattr()以及callable()进行组合使用。
如下所示:
import sys
class YunPan:
"""
this is YunPan.
You can specify start-up parameters on the command line.
If the specified parameter is attribute, this property will be displayed. If the specified parameter is called, the method is performed
The parameters you can specify now are:
Help: Get help information
The method you can specify is:
Download: Test Download Features, Parameters -> Str
UPLOAD: Test Upload Energy, Parameters -> Str
Raises:
TypeError: If there is no such method or attribute in the class, it will throw an exception.
"""
help = __doc__
def __init__(self) -> None:
self.attrOrMethod = sys.argv[1]
self.fileName = sys.argv[2] if len(sys.argv) > 2 else None
self.choices()
def download(self):
print("downloading file : %s"%self.fileName)
def upload(self):
print("uploading file : %s"%self.fileName)
def choices(self):
if not hasattr(self, self.attrOrMethod):
raise TypeError("%s not implement method or attributes:%s"%(self.__class__.__name__, self.attrOrMethod))
attrOrMethod = getattr(self, self.attrOrMethod)
if callable(attrOrMethod):
return attrOrMethod()
print(attrOrMethod)
if __name__ == "__main__":
YunPan()
测试结果:
$ python3 .\demo.py help
this is YunPan.
You can specify start-up parameters on the command line.
If the specified parameter is attribute, this property will be displayed. If the specified parameter is called, the
method is performed
The parameters you can specify now are:
Help: Get help information
The method you can specify is:
Download: Test Download Features, Parameters -> Str
UPLOAD: Test Upload Energy, Parameters -> Str
Raises:
TypeError: If there is no such method or attribute in the class, it will throw an exception.
$ python3 .\demo.py download TestFile
downloading file : TestFile
$ python3 .\demo.py upload TestFile
uploading file : TestFile
$ python3 .\demo.py func ..
TypeError: YunPan not implement method or attributes:func