Python系列 65 自省反射

自省反射

自省和反射是两个比较专业化的术语,释义如下:

  • 自省是指获取对象的能力
  • 反射是指操纵对象的能力

由于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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值