Python系列之反射、面向对象
一、反射
说反射之前先介绍一下__import__方法,这个和import导入模块的另一种方式
1. import commons
2. __import__('commons')
如果是多层导入:
1. from list.text import commons
2. __import__(' list.text.commons',fromlist=True) #如果不加上fromlist=True,只会导入list目录
反射即想到4个内置函数分别为:getattr、hasattr、setattr、delattr 获取成员、检查成员、设置成员、删除成员下面逐一介绍先看例子:
class Foo(object):
def __init__(self):
self.name = 'abc'
def func(self):
return 'ok'
obj = Foo()
#获取成员
ret = getattr(obj, 'func')#获取的是个对象
r = ret()
print(r)
#检查成员
ret = hasattr(obj,'func')#因为有func方法所以返回True
print(ret)
#设置成员
print(obj.name) #设置之前为:abc
ret = setattr(obj,'name',19)
print(obj.name) #设置之后为:19
#删除成员
print(obj.name) #abc
delattr(obj,'name')
print(obj.name) #报错
对于反射小节:
1.根据字符串的形式导入模块。
2.根据字符串的形式去对象(某个模块)中操作其成员
实例:基于反射实现类Web框架的路由系统
实现思路:规定用户输入格式 模块名/函数名 通过__import__的形式导入模块并通过 hasattr和getattr 检查并获取函数返回值。

二、面向对象
面向对象简称OOP,面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。
语法格式见下图:

关键字class 和函数def 是一样的。类名通常是大写开头的单词,定义号类后就可以创建实例如上图的类加()就相当于创建一个类的实例obj
- def Bar(self) 其中self 为形式参数
- 和实例化对象obj的内存地址相同
类的三大特性:封装、继承、多态
1、封装
面向对象编程的一个重要特点就是数据封装。例如:
class Foo:
def fetch(self):
print(self.beckend) #self 直接在对象里面取值 obj = Foo()
obj.beckend = 'www.baidu.com' #把beckend封装在对象里面
obj.fetch()
非主流的用法
class Foo :
'''构造方法'''
def __init__(self,bk):
self.backend = bk # 把obj对象的参数封装在 init 方法里
def fetch(self):
print(self.backend)
def add(self):
print(self.backend)
obj = Foo('www.xxx.com')
obj.fetch()
obj.add()
主流用法
通过代码我们看到__init__:称之为构造方法,需要注意__init__的第一个参数永远是self,表示的实例本身
封装的意义:当同一类型的方法具有相同的参数时,可以直接封装到对象里减少代码量。
使用场景把类当作模版,创建多个对象并且对象内封装的数据可以不同。
2、继承
当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class),有几点要注意:
- 继承要在子类加上父类的类名
- 子类和父类都有的方法,优先找子类的方法
- python里面可以继承多个类C#,java 不可以多继承
- 如果继承多个类,继承顺序为从左至右
例如下面的例子:
class Animals:
def chi(self):
print(self.Name + ' 吃')
def he(self):
print(self.Name + ' 喝') class Dog(Animals):
def __init__(self,name):
self.Name = name
def jiao(self):
print(self.Name + ' 叫')
xxoo =Dog('某某某') xxoo.chi()
xxoo.he()
xxoo.jiao()
继承实例
class Animals:
def chi(self):
print(self.Name +' 吃') def he(self):
print(self.Name + ' 喝') class Uncle:
def du(self):
print(self.Name + ' 赌') class Dog(Animals,Uncle):
def __init__(self,name):
self.Name = name xxoo = Dog('某某某')
xxoo.chi()
xxoo.du()
多继承
关于继承顺序需要注意例如 E继承(C,D) -->C继承(A)-->D继承(B) 如下图(python3):

class A:
def f1(self):
print('A')
class B:
def f(self):
print('B')
class C(A):
def f(self):
print('C')
class D(B):
def f1(self):
print('D') class E(C,D):
def f(self):
print('E')
aa = E()
aa.f1()
类的查找顺序
第二种查找顺序:E继承(C,D)-->C继承(A),D继承(B)-->A和B都继承(Boos) ,查找顺序如下(python3):

class Boos:
def f1(self):
print('Boos') class A(Boos):
def f(self):
print('A')
class B(Boos):
def f(self):
print('B')
class C(A):
def f(self):
print('C')
class D(B):
def f1(self):
print('D') class E(C,D):
def f(self):
print('E') aa = E()
aa.f1()
查找顺序
下面说下python27的查找顺序是什么那?
未继承object为经典类查找顺序--> 深度优先

3、多态
即多种形态....
补充:
关于继承如何执行父类的构造方法那?有两种方法如下代码:
class Annimal:
def __init__(self):
print('Annimal的构造方法') self.ty = '动物' class Cat(Annimal):
def __init__(self):
print('Cat的构造方法')
self.n = '猫'
super(Cat, self).__init__() #推荐用这种
# Annimal.__init__(self) #第二种方式
c = Cat()
执行父类构造方法
查找源码的过程(self.xxxx(),从底层开始找)
三、成员
分别有静态字段、静态方法、类方法、特性、普通字段、普通方法、
class Provice:
#静态字段
country ='China'
def __init__(self,name):
#普通字段
self.name = name
#普通方法
def show(self):
print('show') @staticmethod #静态方法
def xo(arg):
print('xo')
print(arg)
@classmethod #类方法,必须要有个cls参数:自动传入类名
def xxoo(cls):
print('xxoo',cls) def start(self):
print('start')
@property #特性
def end(self):
print('end')
@end.setter
def end(self,values):
print(values)
self.name = values #也可以更改内存里的值 Provice.country #类访问静态字段
Provice.xo('alex') #类访问静态方法
Provice.xxoo() #访问类方法 #获取特性值
obj = Provice('alex')
obj.end
#设置特性值
obj1= Provice('alex')
obj1.end='123'
print(obj1.name) #普通方法
obj1= Provice('alex')
obj1.show() #普通字段
obj1= Provice('alex')
print(obj1.name)
成员小节:
- 自己去访问自己的成员,除了类中的方法
通过类访问的有:静态字段、静态方法、类方法
通过对象访问:普通字段、普通方法 、特性
静态字段:存在类中 ,静态字段存在的意:把对象里面重复的数据只在类里保存一份
静态方法 :没有self 可以传参数,调用的时候也需要传入参数 ,存在的意义:不需要创建对象,就可以访问此方法 ,为类而生
类方法:必须要有个cls参数:自动传入类名
特性 对象调用 、不能加参数,执行不用加括号 普通字段,存放在对象中
普通方法 存在的意义:普通方法如果要想被调用就需要创建self ,为对象而生
各成员存在的意义
四、成员修饰符
公有成员:任何地方都能访问
私有成员:只有在类的内部才能访问,定义方式为命名时,前两个字符为下划线,如 "__test"
class Person:
country = 'China' #静态字段,属于公有成员
__planet = 'Earth' #静态字段,属于私有成员
def __init__(self,name):
print('Person build self.name')
self.name = name def say(self):
print('The planet is %s'%Person.__planet) #在类的内部访问私有静态字段 p1 = Person('Nothing')
p1.say()
print(p1.country) #访问公有静态字段
print(p1.__planet) #访问私有静态字段 #执行结果:
Person build self.name
The planet is Earth #在类的内部可以访问
print(p1.__planet)
China #外部可以访问公有静态字段
AttributeError: 'Person' object has no attribute '__planet' #外部无法访问私有静态字段
小节:私有成员只能在类内部使用,其他的都不能使用包括继承的子类,也不是绝对 也可以通过访问,但是不推荐
对象._类名__字段名
类的特殊成员:
__doc__ 表示类的描述信息
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
__init__ 构造方法,通过类创建对象时,自动触发执行
__call__ 对象后面加括号,触发执行。
__dict__ 类或对象中的所有成员
__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
__init__ 构造方法,通过类创建对象时,自动触发执行 __setitem__,__getitem__,__delitem__ 用于索引操作,如字典。分别表示获取、设置、删除数据
五、异常处理
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
语法:
try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生 finally:
xxxx
标准的异常有:
BaseException 所有异常的基类
SystemExit 解释器请求退出
KeyboardInterrupt 用户中断执行(通常是输入^C)
Exception 常规错误的基类
StopIteration 迭代器没有更多的值
GeneratorExit 生成器(generator)发生异常来通知退出
StandardError 所有的内建标准异常的基类
ArithmeticError 所有数值计算错误的基类
FloatingPointError 浮点计算错误
OverflowError 数值运算超出最大限制
ZeroDivisionError 除(或取模)零 (所有数据类型)
AssertionError 断言语句失败
AttributeError 对象没有这个属性
EOFError 没有内建输入,到达EOF 标记
EnvironmentError 操作系统错误的基类
IOError 输入/输出操作失败
OSError 操作系统错误
WindowsError 系统调用失败
ImportError 导入模块/对象失败
LookupError 无效数据查询的基类
IndexError 序列中没有此索引(index)
KeyError 映射中没有这个键
MemoryError 内存溢出错误(对于Python 解释器不是致命的)
NameError 未声明/初始化对象 (没有属性)
UnboundLocalError 访问未初始化的本地变量
ReferenceError 弱引用(Weak reference)试图访问已经垃圾回收了的对象
RuntimeError 一般的运行时错误
NotImplementedError 尚未实现的方法
SyntaxError Python 语法错误
IndentationError 缩进错误
TabError Tab 和空格混用
SystemError 一般的解释器系统错误
TypeError 对类型无效的操作
ValueError 传入无效的参数
UnicodeError Unicode 相关的错误
UnicodeDecodeError Unicode 解码时的错误
UnicodeEncodeError Unicode 编码时错误
UnicodeTranslateError Unicode 转换时错误
Warning 警告的基类
DeprecationWarning 关于被弃用的特征的警告
FutureWarning 关于构造将来语义会有改变的警告
OverflowWarning 旧的关于自动提升为长整型(long)的警告
PendingDeprecationWarning 关于特性将会被废弃的警告
RuntimeWarning 可疑的运行时行为(runtime behavior)的警告
SyntaxWarning 可疑的语法的警告
UserWarning 用户代码生成的警告
五、单例模式
单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。
用装饰器方式实现
def wapper(cls):
instances = {}
def inner():
if cls not in instances:
instances[cls] = cls()
return cls
return inner @wapper
def Foo():
pass f1 =Foo()
f2 =Foo() print(f1 is f2)
静态方法实现:
class ConnectPool:
__instatnce=None
@staticmethod
def get_instance():
if ConnectPool.__instatnce:
return ConnectPool.__instatnce
else:
ConnectPool.__instatnce = ConnectPool()
return ConnectPool.__instatnce obj =ConnectPool.get_instance()
print(obj)
obj1 =ConnectPool.get_instance()
print(obj1)
Python系列之反射、面向对象的更多相关文章
- Python系列6之面向对象
目录 生成器和迭代器 字符串格式化 内置函数vars 反射 面向对象编程 一. 生成器和迭代器 1. 生成器 生成器具有一种生成的能力,它仅仅代表着一种生成的能力,当我们需要使用的时候,才会通过迭代 ...
- Python系列之 - 反射
一.静态方法(staticmethod)和类方法(classmethod) 类方法:有个默认参数cls,并且可以直接用类名去调用,可以与类属性交互(也就是可以使用类属性) 静态方法:让类里的方法直接被 ...
- Python(六)面向对象、异常处理、反射、单例模式
本章内容: 创建类和对象 面向对象三大特性(封装.继承.多态) 类的成员(字段.方法.属性) 类成员的修饰符(公有.私有) 类的特殊成员 isinstance(obj, cls) & issu ...
- python基础-9__import__ 反射和面向对象基础 self 封装 继承(多继承顺序) 多态
一 反射 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删 ...
- Python基础系列----函数,面向对象,异常
1.前言 前 ...
- python学习笔记六 面向对象相关下(基础篇)
面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以将多函数中公用的变量封装到对象中) 对象,根据模板创建的 ...
- Python之路:面向对象及相关
其他相关 一.isinstance(obj, cls) 检查是否obj是否是类 cls 的对象 class Foo(object): pass obj = Foo() isinstan ...
- Python 基础 三 反射
Python 基础 三 反射 今天我们先介绍一下反射这个概念,啥是反射?反射就是自己检测自己.在我们Python的面向对象中的反射是啥意思呢?就是通过字符串的形式操作对象相关的属性.python中的一 ...
- Python 入门 之 反射
Python 入门 之 反射 1.反射 : (自省) 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省). Python面向对象中的反射:通过字符串的形式操作对象的相关属性.P ...
随机推荐
- java程序的内存分配
java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的 ...
- Windows环境下最新OpenCV和Contribute代码的联合编译
解决这个问题,目的在于获得并使用最新的完全版本的代码,主要方法是对CMake能够熟练使用,并且对编译等基础支持有所了解. 一.工具的准备 1 tortoisegit www.tortoisegit.o ...
- 第2阶段——编写uboot之编译测试以及改进(3)
编译测试: 1.将写好的uboot复制到linux下面 2.make编译,然后将错误的地方修改,生成boot.bin (编译出错的解决方案:http://www.cnblogs.com/lifexy/ ...
- 第1阶段——关于u-boot目标文件start.o中.globl 和.balignl理解(3)
汇编程序中以.开头的名称并不是指令的助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为伪操作. .globl _start 作用:声明一个_start全局符号(Symbol), 这个_sta ...
- Linux — 用户组、权限
Linux 用户组分为:所有者.所在组.其他组 所有者:谁创建,谁是所有者.命令:ls -al 所在组:当创建文件或者文件夹时,这个文件或者文件夹所分配到的用户组,这样就会有效地隔离文件. 其他组:和 ...
- 【1414软工助教】团队作业8——第二次项目冲刺(Beta阶段) 得分榜
题目 团队作业8--第二次项目冲刺(Beta阶段) 往期成绩 个人作业1:四则运算控制台 结对项目1:GUI 个人作业2:案例分析 结对项目2:单元测试 团队作业1:团队展示 团队作业2:需求分析&a ...
- 【Beta】阶段 第二次Daily Scrum Meeting
每日任务 1.本次会议为第二次 Meeting会议: 2.本次会议在周二上午9:40,课间休息时间在禹州楼召开,召开本次会议为10分钟. 一.今日站立式会议照片 二.每个人的工作 (有work ite ...
- 微信小程序中的微信支付js代码和流程详解
微信支付流程 步骤 (一)获取用户的信息 (二)统一下单(返回的prepay_id用于第(三)步的请求参数) (三)发起支付请求 操作(这边假设你已经获得了用户的openId) (一).获取用户ope ...
- Swing-布局管理器之FlowLayout(流式布局)-入门
FlowLayout应该是Swing布局管理器学习中最简单.最基础的一个.所谓流式,就是内部控件像水流一样,从前到后按顺序水平排列,直到达到容器的宽度时跳转到第二行.既然是水平排列,那么就存在三种基本 ...
- 201521123057 《Java程序设计》第2周学习总结
1. 本章学习总结 本周Java教学主要围绕Java的基本语法展开.在本周的学习中,我了解到了: -Integer的取值范围 -if...else条件式,switch条件式,while循环,break ...