32.1-反射基本概念

2019-12-30  本文已影响0人  BeautifulSoulpy

奔跑不单是一种能力,更是一种态度,决定你人生高度的态度。
命运如同手中的掌纹,无论多曲折,终掌握在自己手中!


总结:

  1. 属性就是key-value对,反射方法可以随时对属性进行修改;

反射reflection

运行时,区别于编译时,指的是程序被加载到内存中执行的时候。
反射,reflection,指的是运行时,动态获取对象类型定义信息。一个对象能够在运行时,像照镜子一样,反射出其类型信息。
简单说,在Python中,能够通过一个对象,找出其type、class、attribute或method的能力,称为反射或者自省。

具有反射能力的函数有:type()、isinstance()、callable()、dir()、getattr()

解释型语言:程序不需要编译,程序在运行时才翻译成机器语言,每执行一次都要翻译一次。因此效率比较低。相对于编译型语言存在的,源不是直接翻译成机器语言,而是先翻译成中间代码,再由解释器对中间代码进行解释。
Python/ JavaScript / Perl / Shell等都是解释型语言。

class Point:
    z = 6
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def show(self):
        return self.x,self.y
# 获取类型信息;
p1 = Point(4,5)
print(p1.__dict__)
print(Point.__dict__)
print(Point.show)
#---------------------------------------------------------------------------
{'x': 4, 'y': 5}
{'__module__': '__main__', 'z': 6, '__init__': <function Point.__init__ at 0x000001FE914F0D08>, 'show': <function Point.show at 0x000001FE914F0C80>, '__dict__': <attribute '__dict__' of 'Point' objects>, '__weakref__': <attribute '__weakref__' of 'Point' objects>, '__doc__': None}
<function Point.show at 0x000001FE914F0C80>


class Point:
    z = 6
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def show(self):
        return self.x,self.y
print(p1.__dict__)  
if hasattr(p1,'y'):
    print(getattr(p1,'y'))  # 返回对象的值或缺省值;

setattr(p1,'b',1000) #p1.b=1000
print(p1.__dict__)  # 等价于 getattr(p1,'__dict__')
print(getattr(p1,'__dict__'))
#-------------------------------------------------------------
{'x': 4, 'y': 5, 'b': 1000}
5
{'x': 4, 'y': 5, 'b': 1000}
{'x': 4, 'y': 5, 'b': 1000}

反射的内置函数

内建函数 意义
getattr(object,name[, default]) 通过name返回object的属性值。当属性不存在,将使用default返回,如果没有default,则抛出AttributeError。name必须为字符串
setattr(object,name, value) object的属性存在,则覆盖,不存在,新增
hasattr(object,name) 判断对象是否有这个名字的属性,name必须为字符串
1. getattr
class A(object):
    def __init__(self, name):
        self.name = name
    def method(self):
        print("Your name is {}".format(self.name))

obj = A("joker")
# 如果obj里有name属性就打印self.name,反之打印not find
print(getattr(obj, "name", "not find"))

# 如果obj里有age属性就打印self.age,反之打印not find
print(getattr(obj,"age", "not find"))

# 如果是方法,就打印其地址,反之打印default
print(getattr(obj, "method","default"))

# 如果是方法,就打印其地址,反之打印default
print(getattr(obj,"func", "default"))
----------------------------------------------------------------------
joker
not find
<bound method A.method of <__main__.A object at 0x0000018992FD20B8>>
default
2. hasattr

hasattr()返回的是布尔值,判断对象、模块等中是否存在这个值;

print(hasattr(obj, "name"))
print(hasattr(obj, "age"))
print(hasattr(obj, "method"))
print(hasattr(obj, "func"))
---------------------------------------------------
True
False
True
False
3. setattr

参数是一个对象,一个字符串和一个任意值。字符串可能会列出一个现有的属性或一个新的属性。这个函数将值赋给属性的。该对象允许它提供.

# 如果对象中有name属性,则把"blala"赋值给它
print(setattr(obj, "name", "blala"))
print(getattr(obj, "name"))
----------------------------------------------
None            <---- set成功会返回None
blala

# 如果对象中没有age属性,则创建一个新属性age,将12赋值给它
print(setattr(obj, "age", 12))
print(getattr(obj, "age"))
-----------------------------------------------
None
12

# 如果对象中有method方法,则重写里面的方法
print(setattr(obj, "method", print("OK")))
print(getattr(obj, "method"))
-----------------------------------------------
None
OK

# 如果对象中没有func方法,则创建一个新的方法func
print(setattr(obj, "func", print("func is OK")))
print(getattr(obj, "func"))
----------------------------------------------
None
func is OK
4. delattr

删除模块或者对象中的属性或方法。删除成功会返回None。

print(delattr(obj, "name"))
print(hasattr(obj, "name"))
--------------------------------------
None
False

# 如果不存在,就报异常
print(delattr(obj, "age"))
-------------------------------------
AttributeError: age

# 创建一个新的func
print(setattr(obj, "func", print("func is OK")))
print(delattr(obj, "func"))
print(hasattr(obj, "func"))
--------------------------------------
None            <------ 添加成功返回码
func is OK
None            <------ 删除成功返回码
False

# 对象中原有定义的函数是无法del的,会报异常
print(hasattr(obj, "method"))
print(delattr(obj, "method"))
--------------------------------------
True
AttributeError: method

练习

  1. 命令分发器,通过名称找对应的函数执行。
    思路:名称找对象的方法

上例中使用getattr方法找到对象的属性的方式,比自己维护一个字典来建立名称和函数之间的关系的方式好多了。

上一篇 下一篇

猜你喜欢

热点阅读