奔跑不单是一种能力,更是一种态度,决定你人生高度的态度。
命运如同手中的掌纹,无论多曲折,终掌握在自己手中!
总结:
- 属性就是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
练习
- 命令分发器,通过名称找对应的函数执行。
思路:名称找对象的方法
上例中使用getattr方法找到对象的属性的方式,比自己维护一个字典来建立名称和函数之间的关系的方式好多了。
网友评论