铁乐学python_day23_面向对象进阶1_反射

以下内容大部分摘自博客http://www.cnblogs.com/Eva-J/

isinstance()和issubclass()

两者的返回值都是布尔值

isinstance() 能够检测到继承关系

type() 只能单纯的判断类

isinstance() 判断一个对象和一个类有没有血缘关系

issubclass() 接收两个参数,前一个是子类名,后一个是父类名

如果返回True,说明有父子(继承)关系。

isinstance(obj,cls)检查obj是否是类 cls 的对象
class Foo(object):
pass
obj = Foo() # 实例化
isinstance(obj, Foo) issubclass(sub, super)检查sub类是否是 super 类的派生类
class Foo(object):
pass
class Bar(Foo):
pass
issubclass(Bar, Foo) issubclass可以追溯到更远的源头,例如:
class tuple_A():
pass
class grandfather_B(tuple_A):
pass
class father_C(grandfather_B):
pass
class son_D(father_C):
pass print(issubclass(son_D, tuple_A)) # 返回True,是不是很像吸血鬼家族呢?

反射

1 什么是反射

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

2 python面向对象中的反射:

通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数:

下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

1) hasattr(*args, **kwargs)
def hasattr(*args, **kwargs): # real signature unknown
"""
Return whether the object has an attribute with the given name. This is done by calling getattr(obj, name) and catching AttributeError.
"""
pass 2)getattr(object, name, default=None)
def getattr(object, name, default=None): # known special case of getattr
"""
getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
"""
pass 3)setattr(x, y, v)
def setattr(x, y, v): # real signature unknown; restored from __doc__
"""
Sets the named attribute on the given object to the specified value. setattr(x, 'y', v) is equivalent to ``x.y = v''
"""
pass 4)delattr(x, y)
def delattr(x, y): # real signature unknown; restored from __doc__
"""
Deletes the named attribute from the given object. delattr(x, 'y') is equivalent to ``del x.y''
"""
pass has-有;attr-属性; get-得到;set-设置;del-删除。 例:以下有没有办法不通过A.role(类名.静态变量名)就拿到'Preson'这个值呢?
class A:
role = 'Preson'
def func(self, num):
print('*' * num) ret = input('>>>') # 用户输入role
print(A.__dict__[ret]) # 通过类内置方法__dict__字典[key]的方式可以拿到,但这不是正常行为。 而像 eval(ret) 执行input命令的有严重的安全隐患,不能用!!不然用户输入什么命令你无法控制。
例如用户输入删除根目录的命令等黑客行为。 那么,这时候使用反射中的getattr方法就可以解决: print(getattr(A, 'role')) # 从A的命名空间里找一个属性 ,直接就可以找到这个属性的值
gettattr 使用字符串数据类型的变量名,访问一个命名空间中的名字(变量名,方法)
f = getattr(A,'func');f(1) # 从A的命名空间里找一个方法 ,找到的是这个方法的内存地址
getattr(A, 'func')(1) # 同理,要想执行类中的方法,也可以使用getattr。等同于A.func(1)执行方法。 在类中的反射 正常情况下如果可以拿到这个变量,
那么如果有这个变量的字符串形式,就可以用反射获取到这个值。
找一个属性,直接就可以找到这个属性的值;
找一个方法,找到的是这个方法的内存地址。 hasattr() 判断某命名空间里有没有某变量名,返回布尔值,
getattr() 从命名空间中获取字符串数据类型变量名对应的值。 所以hasattr和getattr是一对好朋友,可以先用hasattr进行if判断再getattr执行
类中的反射--类可以获取类中的属性和方法。 例1:
class Person():
role = 'person'
def __init__(self, name):
self.name = name def super_start(self):
print('巨星指数:'+'*' * 10) MJ = Person('米高积逊')
ret = input('>>>').strip() # 用户交户输入
if hasattr(MJ, ret): # 判断假如用户输入的字符串类型变量名存在
getattr(MJ, ret)() # 则执行类内部方法
else:
print('你的输入有误') # 条件不成立则不执行,保障了程序运行流畅,不至于卡在getattr这一块报错 例2:
class Person():
role = 'person'
def __init__(self, name):
self.name = name def super_start(self):
print('巨星指数:'+'*' * 10) MJ = Person('米高积逊')
print(MJ.super_start) # 打印类内部方法的内存地址
getattr(MJ, 'super_start')()
print(getattr(MJ, 'name'))
setattr(MJ, 'money', 50000000) # 设置属性,若无则新增,若有则修改
print(MJ.__dict__)
delattr(MJ, 'money') # 删除属性
print(MJ.__dict__) 例3:用于模块,可做到接收一个字符串类型变量就执行相应的函数
def login():
print('执行login功能') def register():
print('执行register功能') import sys
print(sys.modules['__main__']) # 打印自身所在py文件(模块) while 1:
order = input('>>>').strip()
if hasattr(sys.modules['__main__'], order):
getattr(sys.modules['__main__'], order)()
else:
print('你输入有误,请重新输入。') 小结
类使用类命名空间中的名字
getattr(类名,'名字') 对象使用对象能用的方法和属性
getattr(对象名,'名字') 模块使用模块中的名字
导入模块
getattr(模块名,'名字')
import os ; getattr(os,'rename')('user','user_info') 从自己所在的模块中使用自己名字
import sys
getattr(sys.modules['__main__'],名字)

end

2018-4-18

铁乐学python_day23_面向对象进阶1_反射的更多相关文章

  1. 铁乐学python_day24_面向对象进阶1_内置方法

    铁乐学python_day24_面向对象进阶1_内置方法 题外话1: 学习方法[wwwh] what where why how 是什么,用在哪里,为什么,怎么用 学习到一个新知识点的时候,多问问上面 ...

  2. python开发面向对象进阶:反射&内置函数

    isinstance和issubclass isinstance(obj,cls)检查是否obj是否是类 cls 的对象或者子类的对象 class Foo(object): pass class ba ...

  3. 铁乐学python_day20_面向对象编程2

    面向对象的组合用法 软件重用的重要方式除了继承之外还有另外一种方式,即:组合 组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合. 例:人狗大战,人类绑定上武器来对狗进行攻击: # 定 ...

  4. 铁乐学python_day22_面向对象编程4

    以下内容大部分摘自博客http://www.cnblogs.com/Eva-J/ 封装 [封装]隐藏对象的属性和实现细节,仅对外提供公共访问方式. [好处] 将变化隔离: 便于使用: 提高复用性: 提 ...

  5. 铁乐学python_day21_面向对象编程3

    抽象类和接口类 以下内容大部分摘自博客http://www.cnblogs.com/Eva-J/ 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某 ...

  6. 铁乐学python_day18-19_面向对象编程1

    以下笔记绝大部分(百分之80或以上)摘自我的授课老师之一:老男孩教育中的景老师. 她上课讲的知识点由浅入深,引人入胜,听她的课完全不会感觉到困阿,而且不知不觉中就感觉掌握了. 她的博客是: http: ...

  7. python ——面向对象进阶(反射,双下线方法,静态方法,类方法)

    属性 如果你已经了解Python类中的方法,那么属性就非常简单了,因为Python中的属性其实是普通方法的变种. 哎,其实就是这样,我们看一下当我们想查看税后工资的时候,这其实是一个人的属性,但是它却 ...

  8. [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦

    [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...

  9. [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程

    [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...

随机推荐

  1. 这个PHP无解深坑,你能解出来吗?(听说能解出来的都很秀)

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由horstxu发表于云+社区专栏 1. 问题背景 PHP Laravel框架中的db migration是比较常用的一个功能了.在每个 ...

  2. 关于打开fiddler后电脑无法正常上网的解决办法(fiddler抓包时的设置)

    关于fiddler如何抓取  ie内容(其中:360浏览器和qq浏览器均使用ie内核) 1.打开fiddler,进入tools-options,设置如下.这样配置后,打开fiddler,fiddler ...

  3. [CTSC 2018]假面

    Description 题库链接 有 \(n\) 个敌方单位,初始第 \(i\) 个单位的血量为 \(m_i\) .共 \(Q\) 次操作,分两种: 对某一个单位以 \(p\) 的概率造成 \(1\) ...

  4. 【VUE】vue项目开发中,setTimeout等定时器的管理。

    如果在一个组件中使用了定时器,当通过路由切换页面的时候 1.如果有同一个组件,定时器会叠加. 解决方案: computed:{ timer: { set (val) { this.$store.sta ...

  5. DOM-访问元素

    id:元素在文档中唯一标识符. title:有关元素的附加说明信息,一般通过工具提示条显示出来. lang:元素内容的语言编码,很少使用 dir:语言方向,职位“Ltr”(从左至右).Rtl(从右至左 ...

  6. (一)面向对象的javascript

    javascript是一门典型的动态类语言 一:鸭式辨型(指导我们关注对象的行为,而不关注对象本身). var duck = { duckString: function(){ console.log ...

  7. $("input[name=name]").val(); 无法获取值问题

    <input type="text" class="text" name="name" placeholder= 例如:上海" ...

  8. 【模板 && 拓扑】 Dijkstra 单源最短路径算法

    话不多说上代码 链式前向星233 #include<bits/stdc++.h> using namespace std; ,_max=0x3fffffff; //链式前向星 struct ...

  9. Java注解(三)

    上一篇了解了自定义注解的使用,不过里面的例子没有多大使用价值,这一回来个有用点的Demo. 目标:将实体bean保存到数据库 先来定义一个实体注解 import java.lang.annotatio ...

  10. PHP CURL库学习

    基本请求步骤 : // . 初始化 $ch = curl_init(); // . 设置选项,包括URL curl_setopt($ch, CURLOPT_URL, "http://www. ...