面向对象基础

面向对象编程

面向过程编程:类似于工厂的流水线

  • 优点:逻辑清晰
  • 缺点:扩展性差

面向对象编程:核心是对象二字,对象属性和方法的集合体,面向对象编程就是一堆对象交互

  • 优点:扩展性强
  • 缺点:逻辑非常乱

类与对象

  • 对象:属性和方法的集合体

  • 类:一系列相同属性和方法的集合体

现实世界中先有对象后有类,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,判断是否为其子类

反射

  1. hasattr:通过字符串判断是否类属性存在
  2. getattr:通过字符串获取类属性
  3. setattr:通过字符串修改类属性
  4. 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 面向对象的更多相关文章

  1. JAVA_SE基础——25.面向对象练习

    黑马程序员入学blog ... 昨晚我写了篇面向对象的内存分析,今天我们来做个小练习.. 需求: 使用java描述一个车与修车厂两个事物, 车具备的公共属性:轮子数. 名字. 颜色 ,还 具备跑的功能 ...

  2. day 25 面向对象之接口、抽象类、多态、异常处理、反射、断言

    复习 '''继承​1.父类:在类后()中写父类们class A:passclass B:passclass C(A, B):pass​2.属性查找顺序:自己 -> ()左侧的父类 -> 依 ...

  3. python基础(25):面向对象三大特性二(多态、封装)

    1. 多态 1.1 什么是多态 多态指的是一类事物有多种形态. 动物有多种形态:人,狗,猪. import abc class Animal(metaclass=abc.ABCMeta): #同一类事 ...

  4. day21_7.25 面向对象之继承

    一.继承 什么是继承? 继承是一种关系,就是描述两者之间什么是什么的关系. 在程序中,继承描述的是类与类之间的关系. 例如a如果继承了b,a就具备了b的所有变量与方法,可以直接调用. class B: ...

  5. 25 面向对象设计实例——基于PCL点云库的通用工具开发

    0 引言 问题背景:pcl中提供了大量工具,用于对点云和三角面片文件进行处理和显示.在研究中,存在很多简易的需求,比如点云坐标转换,点云的打开显示以及同步显示,点云的最小包络求解,点云的格式转换等等. ...

  6. 25 面向对象编程 继承概念 代码 快捷键 super注意点

    继承概念 继承的本质是对某一批的抽象,从而实现对现实世界更美好的建模. extends的意思的"扩展".子类是父类的扩展. JAVA中类只有单继承,没有多继承!理解:一个儿子只能有 ...

  7. Python3学习(2)-中级篇

    Python3学习(1)-基础篇 Python3学习(2)-中级篇 Python3学习(3)-高级篇 切片:取数组.元组中的部分元素 L=['Jack','Mick','Leon','Jane','A ...

  8. Java学习笔记【持续更新】

    一个简单的java程序如下: class Sakura { public static void main(String[] arges) { system.out.println("Hel ...

  9. 从Python到Web开发

    基础部分: 1-编程基础及Python环境部署 2-Python基础语法-内存管理-运算符-程序控制 3-Python内置结构-列表 4-Python数据类型之元组-字符串 5-python的封装与结 ...

随机推荐

  1. 洛谷——P1106 删数问题

    https://www.luogu.org/problem/show?pid=1106 题目描述 键盘输入一个高精度的正整数N,去掉其中任意k个数字后剩下的数字按原左右次序将组成一个新的正整数.编程对 ...

  2. 一次源码编译PHP折腾记

    前言LINUX环境下编译安装是很折腾人的一件事情,如果没有C/C++功底,碰到编译器报错,肯定要抓狂了 :):),有些软件需要依赖其它库,必须先把依赖库安装好才能进行软件安装.当你学会了编译安装神技之 ...

  3. SharePoint 2013:解决爬网出错的问题

    现象: 以前一直正常的爬网突然无法顺利完成,总是在进行到某个部分就停滞不前. 调查: 在查看了log文件后,发现了这条错误 06/24/2014 11:14:51.86   NodeRunnerQue ...

  4. find -perm命令

    http://www.2cto.com/os/201205/130125.html find -perm,根据文件的权限来查找文件,有三种形式: find -perm mode find -perm ...

  5. jquery easyui datagrid实现数据改动

    1.单击选中待改动行 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA= ...

  6. jquery选中表格的某行变色

    <tr ng-click="+"selectRow("+i+");"+" ng-mouseover="+"chan ...

  7. 1tb等于多少g 1TB和500G有什么区别

    转自:http://www.a207.com/article/view_39392 移动硬盘.U盘是生活中常见的用品,他们的内存大小是什么标准.很多人对于1tb等于多少g和1tb和500g有什么区别不 ...

  8. 第2章 安装Nodejs 2-3 Windows下安装Nodejs

    http://nodejs.org

  9. nodejs express开发

    用NodeJS+Express开发WEB应用---第一篇 大漠穷秋2014-03-28 预热 为了对后面的内容理解更加透彻,推荐首先阅读下面这篇很好的文章: http://www.nodebeginn ...

  10. UILabel垂直方向显示(上下的顺序显示)。

    NSString* text = @"一"; NSDictionary *attribute = @{NSFontAttributeName: [UIFont systemFont ...