python可以实现什么黑科技_Python中的“黑科技”:内省(Introspection)与反射(Reflection)...

内省与反射对于编程语言来说,是非常重要的特性,对Python同样如此。如果灵活运营,可以大大提高我们对代码的掌控能力。今天,小编就来带大家看一看Python中的这两项“黑科技”。

u=1198920076,369619582&fm=173&app=25&f=JPEG?w=533&h=326&s=FCBF30D4405409CE0DB7738B0300F09C

内省

内省,有时也叫类型内省,是在运行时进行的一种对象检测机制。我们可以通过内省来获取一个对象的所有信息,比如这个对象的类型,其中包含哪些属性等等。让我们来看两个例子:

例子1:dir()

dir()是内省机制中的一个重要内置函数。这个函数可以将一个对象的所有属性以字符串列表的形式返回。

u=4067727999,2270159768&fm=173&app=25&f=JPEG?w=640&h=319&s=3A91A1440AE0BD7806E8158F0000F082

这段代码的输出为:

>>> ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'foo', 'get_foo']

在这些属性当中,除了我们自己定义的“foo”和“get_foo”以外,其它的都是Python对象自带的属性。

例子2:类型检查

类型检查的方法有很多种,比如:

u=3786127623,3066861597&fm=173&app=25&f=JPEG?w=640&h=254&s=3295A16C7EE09F7004C9CD0F0000E0C1

注意,在使用isinstance()时有一个坑,那就是对于有继承关系的两个类,它的结果始终是True。

比如下面这两个类,logging.FileHandler继承自logging.StreamHandler。尽管这两个类并不相同,但是isinstance()的结果是True。

u=2661851282,1687578762&fm=173&app=25&f=JPEG?w=640&h=191&s=3295E16CCFECBF70047D908E0000F0C2

除了上面举的例子,Python中利用内省还能做很多事情。下面,我们用inspect模块来实现一个很二的功能:用一个装饰器来检测一个对象是类还是函数。

u=908337840,671547049&fm=173&app=25&f=JPEG?w=640&h=828&s=3291A16CDAAE956C065CFC830000E0C2

反射

与内省相比,反射的功能要显得更为强大。反射使得程序具有在运行时动态修改自己的结构和行为的能力。继续来看几个例子:

例子1:动态设置属性

假设有一个空模块,现在我们想把所有的环境变量作为属性添加到这个模块中。这个文件env.py可以这样实现:

u=555244065,1742240868&fm=173&app=25&f=JPEG?w=640&h=163&s=3291A16CCFE4BB704E595C860000E081

import_module(__name__)把当前模块作为一个对象返回,setattr() 将环境变量的key,value值作为属性添加到模块中去。

事实上,import_module(__name__)也是利用里Python的反射能力。它根据输入的字符串参数生成了一个模块对象。

例子2:用getattr()动态获取属性值

在另一个文件output.py中,我们导入env.py,然后实现一个函数,获取其中的所有环境变量参数并以字典的形式返回:

u=805892944,4090131356&fm=173&app=25&f=JPEG?w=640&h=396&s=3293A16C52F4BE6C445D4D8E0000A082

内置函数getattr()允许我们根据属性名来获取属性的值。

例子3:动态方法

下面小编要放大招了。我们要实现一个动态方法,当这个方法被调用时,它甚至都还没有被定义,但是仍然能够被成功调用。这是如何实现的呢?我们来看代码:

u=174086480,2379102287&fm=173&app=25&f=JPEG?w=640&h=522&s=3297A16CDAA6876C4C7574030000E0C1

这段代码看起来可能有点烧脑。总的来说,我们创建了一个GreetMe对象,并且依次调用其hello(),bye()和nice_to_meet_you()方法。然而,这三个方法在GreetMe类中均没有定义。

这里面的关键在于__getattr__()方法。在Python中,当一个没有被定义的方法被访问时,__getattr__() 就会被调用。后面的事情就靠大家自己去理解了。

好了,今天的“黑科技”就先讲到这里。感兴趣的小伙伴可以留言交流。

感谢大家的阅读!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值