32.1-反射基本概念

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


总结:

  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方法找到对象的属性的方式,比自己维护一个字典来建立名称和函数之间的关系的方式好多了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352