Day 25 面向对象
面向对象基础
面向对象编程
面向过程编程:类似于工厂的流水线
- 优点:逻辑清晰
- 缺点:扩展性差
面向对象编程:核心是对象二字,对象属性和方法的集合体,面向对象编程就是一堆对象交互
- 优点:扩展性强
- 缺点:逻辑非常乱
类与对象
对象:属性和方法的集合体
类:一系列相同属性和方法的集合体
现实世界中先有对象后有类,python中先有类,再实例化出对象
对象的属性的查找顺序
先对象本身-->类-->父类-->父类的父类-->object-->自己定制的元类-->type
给对象定制独有属性
class People:
pass
p1 = Peolple()
p1.name = 'nick'
p2 = People()
p2.name = 'tank'
对象的绑定方法
class People:
def eat(self):
print(self, 'eat....')
p1 = Peolple()
p1.eat()
p1.name = 'nick'
p2 = People()
p2.eat()
p2.name = 'tank'
类与数据类型
lis = [1,2,3] # lis = list([1,2,3])
class foo:
def __init__(self,name):
self.name = name
f = foo('name')
lis.append(4) # 对象调对象绑定的方法,会自动传参
list.append(lis,4) # 类调用对象绑定的方法,必须得传参
面向对象进阶
类的继承
继承父类,则会有父类的所有属性和方法
class ParentClass1():
pass
class ParentClass2():
pass
class SubClass(ParentClass1,ParentClass2):
pass
类的派生
继承父类的同时自己有init,然后也需要父类的init
class ParentClass1():
def __init__(self,name):
pass
class SubClass(ParentClass):
def __init__(self,age):
# 1. ParentClass1.__init__(self,name)
# 2. super(SubClass,self).__init__(name)
self.age = age
类的组合
类对象可以引用/当做参数传入/当做返回值/当做容器元素,类似于函数对象
class ParentClass1():
count = 0
def __init__(self,name):
pass
class SubClass(ParentClass):
def __init__(self,age):
self.age = age
pc = ParentClass1()
sc = SubClass()
sc.parent_class = pc # 组合
sc.parent_class.count # 0
菱形继承问题
新式类:继承object的类,python3中全是新式类
经典类:没有继承object的类,只有python2中有
在菱形继承的时候,新式类是广度优先(老祖宗最后找);经典类深度优先(一路找到底,再找旁边的)
多态与多态性
一种事物的多种形态,动物-->人/猪/狗
# 多态
import abc
class Animal(metaclass=abc.ABCmeta):
@abc.abstractmethod
def eat():
print('eat')
class People(Animal):
def eat():
pass
class Pig(Animal):
def eat():
pass
def run():
pass
class Dog(Animal): # 报错
def run():
pass
# 多态性
peo = People()
peo.eat()
peo1 = People()
peo1.eat()
pig = Pig()
pig.eat()
def func(obj):
obj.eat()
class Cat(Animal):
def eat():
pass
cat = Cat()
func(cat)
鸭子类型:只要长得像鸭子,叫的像鸭子,游泳像鸭子,就是鸭子.
类的封装
隐藏属性,只有类内部可以访问,类外部不可以访问
class Foo():
__count = 0
def get_count(self):
return self.__count
f = Foo()
f.__count # 报错
f._Foo__count # 不能这样做
类的property特性
把方法变成属性引用
class People():
def __init__(self,height,weight):
self.height = height
self.weight = weight
@property
def bmi(self):
return weight/(height**2)
@bmi.setter
def bmi(self,value)
print('setter')
@bmi.deleter
def bmi(self):
print('delter')
peo = People
peo.bmi
类与对象的绑定方法和非绑定方法
没有任何装饰器装饰的方法就是对象的绑定方法, 类能调用, 但是必须得传参给self
被 @classmethod 装饰器装饰的方法是类的绑定方法,参数写成cls, cls是类本身, 对象也能调用, 参数cls还是类本身
被 @staticmethod 装饰器装饰的方法就是非绑定方法, 就是一个普通的函数
面向对象高级
isinstance,issubclass
isinstance判断是否为类的实例化对象,会检测父类,而type不会检测父类
issubclass,判断是否为其子类
反射
- hasattr:通过字符串判断是否类属性存在
- getattr:通过字符串获取类属性
- setattr:通过字符串修改类属性
- delattr:通过字符串删除类属性
call
class Foo:
def __init__(self):
print('Foo()会触发我')
def __call__(self):
print('Foo()()/f()会触发我')
f = Foo()
f()
new
class Foo:
def __new__(self):
print('new')
obj = object.__new__(self)
return obj
def __init__(self):
print('init')
f = Foo()
元类
元类用来造类的
元类()-->类-->init
元类()()-->对象--->call
类分为几部分:类名/类体名称空间/父类们
class Mymeta(type):
def __init__(self,class_name,class_bases,class_dic):
# 控制类的逻辑代码
super().__init__(class_name,class_bases,class_dic)
def __call__(self,*args,**kwargs):
# 控制类实例化的参数
obj = self.__new__(self) # obj就是实例化的对象
self.__init__(obj,*args,**kwargs)
print(obj.__dict__)
# 控制类实例化的逻辑
return obj
class People(metaclass=Mymeta):
def __init__(self,name,age):
self.name = name
self.age = age
单例模式
利用类的绑定方法的特性
NAME = 'nick'
AGE = 18
class People():
__instance = None
@classmethod
def from_conf(cls):
if cls.__instance:
return cls.__instance
cls.__instance = cls(NAME,AGE)
return cls.__instance
People.from_conf()
People.from_conf()
利用装饰器
NAME = 'nick'
AGE = 18
def deco(cls):
cls.__instance = cls(NAME,AGE)
def wrapper(*args,**kwargs):
if len(args) == 0 and len(kwargs) == 0:
return cls.__instance
res = cls(*args,**kwargs)
return res
return wrapper
@deco
class People():
def __init__(self,name,age):
self.name = name
self.age = age
peo1 = People()
peo2 = People()
利用元类(正宗的)
NAME = 'nick'
AGE = 18
class Mymeta(type):
def __init__(self,class_name,class_bases,class_dict):
super().__init__(class_name,class_bases,class_dict)
self.__instance = self(NAME,AGE)
def __call__(self,*args,**kwargs):
if len(args) == 0 and len(kwargs) == 0:
return self.__instance
obj = object.__new__(self)
self.__init__(obj,*args,**kwargs)
return obj
class People(metaclass=Mymeta):
def __init__(self,name,age):
self.name = name
self.age = age
peo1 = People()
peo2 = People()
异常处理
捕捉异常
x = 10
y = 20
c = 30
try:
1/0
except Exception as e:
print(e)
raise
抛出异常
raise KeyboardInterrupt('中断捕捉')
assert
判断某一行代码是否有问题
Day 25 面向对象的更多相关文章
- JAVA_SE基础——25.面向对象练习
黑马程序员入学blog ... 昨晚我写了篇面向对象的内存分析,今天我们来做个小练习.. 需求: 使用java描述一个车与修车厂两个事物, 车具备的公共属性:轮子数. 名字. 颜色 ,还 具备跑的功能 ...
- day 25 面向对象之接口、抽象类、多态、异常处理、反射、断言
复习 '''继承1.父类:在类后()中写父类们class A:passclass B:passclass C(A, B):pass2.属性查找顺序:自己 -> ()左侧的父类 -> 依 ...
- python基础(25):面向对象三大特性二(多态、封装)
1. 多态 1.1 什么是多态 多态指的是一类事物有多种形态. 动物有多种形态:人,狗,猪. import abc class Animal(metaclass=abc.ABCMeta): #同一类事 ...
- day21_7.25 面向对象之继承
一.继承 什么是继承? 继承是一种关系,就是描述两者之间什么是什么的关系. 在程序中,继承描述的是类与类之间的关系. 例如a如果继承了b,a就具备了b的所有变量与方法,可以直接调用. class B: ...
- 25 面向对象设计实例——基于PCL点云库的通用工具开发
0 引言 问题背景:pcl中提供了大量工具,用于对点云和三角面片文件进行处理和显示.在研究中,存在很多简易的需求,比如点云坐标转换,点云的打开显示以及同步显示,点云的最小包络求解,点云的格式转换等等. ...
- 25 面向对象编程 继承概念 代码 快捷键 super注意点
继承概念 继承的本质是对某一批的抽象,从而实现对现实世界更美好的建模. extends的意思的"扩展".子类是父类的扩展. JAVA中类只有单继承,没有多继承!理解:一个儿子只能有 ...
- Python3学习(2)-中级篇
Python3学习(1)-基础篇 Python3学习(2)-中级篇 Python3学习(3)-高级篇 切片:取数组.元组中的部分元素 L=['Jack','Mick','Leon','Jane','A ...
- Java学习笔记【持续更新】
一个简单的java程序如下: class Sakura { public static void main(String[] arges) { system.out.println("Hel ...
- 从Python到Web开发
基础部分: 1-编程基础及Python环境部署 2-Python基础语法-内存管理-运算符-程序控制 3-Python内置结构-列表 4-Python数据类型之元组-字符串 5-python的封装与结 ...
随机推荐
- 洛谷——P1106 删数问题
https://www.luogu.org/problem/show?pid=1106 题目描述 键盘输入一个高精度的正整数N,去掉其中任意k个数字后剩下的数字按原左右次序将组成一个新的正整数.编程对 ...
- 一次源码编译PHP折腾记
前言LINUX环境下编译安装是很折腾人的一件事情,如果没有C/C++功底,碰到编译器报错,肯定要抓狂了 :):),有些软件需要依赖其它库,必须先把依赖库安装好才能进行软件安装.当你学会了编译安装神技之 ...
- SharePoint 2013:解决爬网出错的问题
现象: 以前一直正常的爬网突然无法顺利完成,总是在进行到某个部分就停滞不前. 调查: 在查看了log文件后,发现了这条错误 06/24/2014 11:14:51.86 NodeRunnerQue ...
- find -perm命令
http://www.2cto.com/os/201205/130125.html find -perm,根据文件的权限来查找文件,有三种形式: find -perm mode find -perm ...
- jquery easyui datagrid实现数据改动
1.单击选中待改动行 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA= ...
- jquery选中表格的某行变色
<tr ng-click="+"selectRow("+i+");"+" ng-mouseover="+"chan ...
- 1tb等于多少g 1TB和500G有什么区别
转自:http://www.a207.com/article/view_39392 移动硬盘.U盘是生活中常见的用品,他们的内存大小是什么标准.很多人对于1tb等于多少g和1tb和500g有什么区别不 ...
- 第2章 安装Nodejs 2-3 Windows下安装Nodejs
http://nodejs.org
- nodejs express开发
用NodeJS+Express开发WEB应用---第一篇 大漠穷秋2014-03-28 预热 为了对后面的内容理解更加透彻,推荐首先阅读下面这篇很好的文章: http://www.nodebeginn ...
- UILabel垂直方向显示(上下的顺序显示)。
NSString* text = @"一"; NSDictionary *attribute = @{NSFontAttributeName: [UIFont systemFont ...