1. 类的反射

程序对自己内部代码的一种自省方式。
定义:通过字符串取操作对象的方式。
可应用于实例对象、类、本模块、其他模块。 带有点 . 的方式都可用反射方法。
四种方法:
1. hasattr(object, name) # 判断、检测
2. getattr(object, name) # 获取
3. setattr(object, name) # 设置
4. delattr(object, name) # 删除属性

1.1 实例对象

class A:
country = '中国' def __init__(self,name,age):
self.name = name
self.age = age def func(self):
print('in A func') obj = A("meet", 18) print(hasattr(obj, 'name')) # True 检测是否有name属性
print(hasattr(obj, 'sex')) # False print(getattr(obj, 'name')) # 获取obj的name属性
print(getattr(obj, 'sex', None))
#指定获取不到,返回None
getattr(obj,'func')()
# 调用obj的func方法,自动将obj地址传入参数中
if hasattr(obj, 'func'):
getattr(obj, 'func')() setattr(obj, 'sex', '男') # 给obj增加 sex='男' 属性
deltattr(obj,'name') # 删除obj的name属性
print(obj.__dict__)

1.2 类

# 通过类名
class A:
country = '中国' def __init__(self,name,age):
self.name = name
self.age = age def func(self):
print('in A func') if hasattr(A, 'country')
print(getattr(A, 'country')) # 中国 if hasattr(A, 'func'):
obj = A("meet", 18)
getattr(A, 'func')(obj)
#或:getattr(obj,'func')()

1.3 其他模块 -- 其他.py文件

# 名字为 tbjx.py 的文件

name = "太白金星"

def func():
print("这是func函数") class C:
area = '北京' def __init__(self, name):
self.name = name def func1(self):
print('in C func1')
# 本文件
import tbjx # 导入 print(getattr(tbjx,'name')) # 获取变量name
getattr(tbjx, 'func')() # 执行func函数 obj = getattr(tbjx,'C')('meet') # 实例化对象 print(getattr(tbjx.C, 'area')) # 查找C类的area属性 ret = getattr(tbjx,'C') # 实例化对象后执行类的func1方法
obj = ret('meet')
getattr(obj, 'func')()

1.4 本模块 -- 当前.py文件

import sys
sys.modules[__name__] # 获取当前py文件的模块对象
def func1():
print('in func1') def func2():
print('in func2') def func3():
print('in func3') def func4():
print('in func4') import sys
content = input('请输入:') # 输入函数名
ret = sys.modules[__name__] # 获取本文件模块的对象
getattr(ret, content)()
class User:
user_list = [('login', '登录'), ('register', '注册'), ('save', '存储')] def login(self):
print('欢迎来到登录页面') def register(self):
print('欢迎来到注册页面') def save(self):
print('欢迎来到存储页面') while True:
obj = User()
for i in enumerate(obj.user_list, 1):
print(f'{i[0]}.{i[1][1]}')
choose = input('请输入序号:').strip()
getattr(obj, obj.user_list[int(choose)-1][0])()

2. 函数与方法的区别

2.1区别的方法:

方法一:
通过打印函数名的方式。 通过类名调用的方法是函数,通过对象调用类中的实例方法,是方法。
方法二:借助模块
from types import FunctionType
from types import MethodType
from types import FunctionType
from types import MethodType def func():
pass class A:
def func(self):
pass
obj = A() print(isinstance(func,FunctionType)) # True
print(isinstance(A.func,FunctionType)) # True
print(isinstance(obj.func,FunctionType)) # False
print(isinstance(obj.func,MethodType)) # True

2.2 总结

总结:
函数都是显性传参,方法都是隐形传参;
类方法是一个方法,静态方法是一个函数。
扩展:Java中只有方法,C中只有函数,C++么,则取决于是否在类中。

3. 特殊的双下方法

​ 原本是开发python这个语言的程序员用的,源码中使用的。不能轻易使用、使用。

3.01 __len__ (len一下对象就触发)

class B:
def __len__(self):
print(666) b = B()
len(b) # len 一个对象就会触发 __len__方法。 # 返回a对象的属性的个数
class A:
def __init__(self):
self.a = 1
self.b = 2 def __len__(self):
return len(self.__dict__)
a = A()
print(len(a))

3.02 __hash__ (hash一下对象就触发)

class A:
def __init__(self):
self.a = 1
self.b = 2 def __hash__(self):
return hash(str(self.a)+str(self.b))
a = A()
print(hash(a)) # 若本类没有,就会从object父类找

3.03 __str__ (打印对象触发、str()也会触发)

class A:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f'姓名:{self.name} 年龄:{self.age}'
# 必须是 return 字符串
a = A('meet', 18)
print(a) # 触发

3.04 __repr__ (打印对象和repr()都会触发)

class A:
def __init__(self):
pass
def __repr__(self):
return '太白'
a = A()
print(repr(a))
print('%r'%a) # 优先级低于str

3.05 __call__ (对象名(),触发)

class Foo:

    def __init__(self):
pass def __call__(self, *args, **kwargs): print('__call__') obj = Foo() # 执行 __init__
obj() # 执行 __call__

3.06 __eq__ (打印对象触发)

class A:
def __init__(self):
self.a = 1
self.b = 2 def __eq__(self,obj):
if self.a == obj.a and self.b == obj.b:
return True
a = A()
b = A()
print(a == b) # 触发

3.07 __del__ (析构方法)

析构方法,当对象在内存中被释放时,自动触发执行。
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

3.08 __new__ (构造方法 类名()触发)

class A:
def __init__(self):
self.x = 1
print('in init function')
def __new__(cls, *args, **kwargs):
print('in new function')
return object.__new__(A, *args, **kwargs) a = A() #触发
print(a.x) # 类名(),触发object类的__new__方法,产生了一个对象空间并返回到 类名(), 再触发__init__方法,封装对象属性。

单例模式:

一个类只允许实例化一个对象。 将对象唯一化(延用同一个对象空间)。
方便对实例个数的控制并节约系统空间。 如:电脑的任务管理器。
class A:
__instance = None
def __new__(cls, *args, **kwargs):
if cls.__instance is None:
obj = object.__new__(cls)
cls.__instance = obj
return cls.__instance
obj = A()
print(obj)
obj1 = A()
print(obj1) # 两次地址相同

python 26 反射的更多相关文章

  1. python的反射机制

    转载自:http://www.cnblogs.com/feixuelove1009/p/5576206.html 对编程语言比较熟悉的朋友,应该知道"反射"这个机制.Python作 ...

  2. python的反射

    目前大多数网站都是通过路由的方法来,处理url请求,如果有很多个url的话,不停的include或者用if判断匹配,似乎不太符合情理,因此这里讲讲python的反射机制, 自动装在模块.请看下面的实例 ...

  3. 简单谈谈python的反射机制

    转:http://www.jb51.net/article/87479.htm 本文主要介绍python中的反射,以及该机制的简单应用,熟悉JAVA的程序员,一定经常和Class.forName打交道 ...

  4. 【转】简单谈谈python的反射机制

    [转]简单谈谈python的反射机制 对编程语言比较熟悉的朋友,应该知道“反射”这个机制.Python作为一门动态语言,当然不会缺少这一重要功能.然而,在网络上却很少见到有详细或者深刻的剖析论文.下面 ...

  5. Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究

    Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: ​ 反射的概念是由Smith在1982年首次提出的 ...

  6. 第六章:Python基础の反射与常用模块解密

    本课主题 反射 Mapping 介绍和操作实战 模块介绍和操作实战 random 模块 time 和 datetime 模块 logging 模块 sys 模块 os 模块 hashlib 模块 re ...

  7. Python中反射的简单应用

    ● 共两个文件:userInfo,reflex.py alex|123456|Manager hezewei|666|Student taibai|2222|Teachar userInfo #!/u ...

  8. Python之反射,正则

    本节主要内容: 一. 反射: getattr hasattr setattr defattr 二. 补充模块中特殊的变量 三. 正则表达式 re模块 (一)反射: hasattr(object, na ...

  9. 关于PYTHON的反射,装饰的练习

    从基本概念,简单例子才能慢慢走到高级一点的地方. 另外,PYTHON的函数式编程也是我很感兴趣的一点. 总体而言,我觉得OOP可以作大的框架和思路,FP能作细节实现时的优雅牛X. ~~~~~~~~~~ ...

随机推荐

  1. 【Arduino】66种传感器模块系列实验(2)---光敏电阻模块

    实验二:光敏电阻传感器模块我手里这块是三针版的,挺秀气吧 光敏电阻是用硫化隔或硒化隔等半导体材料制成的特殊电阻器,其工作原理是基于内光电效应.光照愈强,阻值就愈低,随着光照强度的升高,电阻值迅速降低, ...

  2. Java IO 为什么我们需要缓冲区

    在执行IO操作我们通常会设置一个字节数组作为缓冲区用来写/读数据,一般情况下一个合理大小的缓冲区是有利于提升性能的,但是有一个问题一直困扰着我,为什么缓冲区可以提升IO操作的性能? 经查阅资料之后,总 ...

  3. C++多小球非对心弹性碰撞(HGE引擎)

    程序是一个月前完成的,之前一直没正儿八经的来整理下这个程序,感觉比较简单,不过即使简单的东西也要跟大家分享下. 源码下载:http://download.csdn.net/detail/y851716 ...

  4. javascript基础学习第二天

    ECMASCRIPT(语法标准) 1. 能够写出简单的逻辑程序代码 2. 变量,数据类型,运算符,条件判断语句,循环语法,数组,对象,函数 1. 赋值运算符 = 将'='右侧的结果赋值给左侧的变量 a ...

  5. PC端触底效果反复触发的解决方案

    最近在做一个PC端的项目,要求是在滑动到页面的底部的时候就动态的加载下一页的数据,代码实现思路如下: 首先,我们需要知道浏览器中有三个高度,分别是屏幕高度(outerHeight),文档容器高度(in ...

  6. mysql语句汇总

      MySQL常用命令: show databases; 显示数据库 create database name; 创建数据库 use databasename; 选择数据库 drop database ...

  7. 05-k8s调度器、预选策略、优选函数

    目录 k8s调度器.预选策略.优选函数 节点选择过程 调度器 预选策略 优选函数 高级调度设置机制 node选择器/node亲和调度 pod亲和性 污点调度 Taints 与 Tolerations ...

  8. Python装饰器 (转)

    多个装饰器执行的顺序就是从最后一个装饰器开始,执行到第一个装饰器,再执行函数本身. #多个装饰器 import time def deco01(func): def wrapper(*args, ** ...

  9. git远程服务器回滚

    1.git log查找commit hash 2.git reset --hard hash 回滚本地git库 3.git push -f origin(git仓库的url) branch名 强制提交

  10. vue动态表单

    项目需求,需要根据后台接口返回数据,动态添加表单内容 说明:此组件基于Ant Design of Vue 目前支持六种表单控件:文本输入框(TextInput).文本域输入框(TextArea).下拉 ...