面向对象基础

面向对象编程

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

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

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

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

类与对象

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

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

现实世界中先有对象后有类,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. EasyUI 在textbox里面输入数据敲回车后查询和普通在textbox输入数据敲回车的区别

    EasyUI实现回车键触发事件 $('#id').textbox('textbox').keydown(function (e) { if (e.keyCode == 13) { alert('ent ...

  2. ubuntu上java的开发环境 jdk 的安装

    jre下载路径: https://java.com/zh_CN/download/manual.jsp jdk下载路径:http://www.oracle.com/technetwork/java/j ...

  3. 使用Fiddler进行抓包

    参考:http://blog.csdn.net/gld824125233/article/details/52588275 1.手机跟电脑需要使用同一个局域网  如果是台式机需要将手机的mac地址让运 ...

  4. 使用Memcached改进Java企业级应用性能:架构和设置

    Memcached由Danga Interactive开发.用来提升LiveJournal.com站点性能. Memcached分布式架构支持众多的社交网络应用,Twitter.Facebook还有W ...

  5. PL/SQL Developer使用技巧、快捷键(转发)

    转发自:https://www.cnblogs.com/linjiqin/archive/2013/06/24/3152538.html PL/SQL Developer使用技巧.快捷键 1.类SQL ...

  6. C#获取本机Sql Serverserver名

    private void Form2_Load(object sender, EventArgs e) { listBox1.Items.Clear(); SQLDMO.Application SQL ...

  7. luogu1064 金明的预算方案

    这道题我就想说一点:审题!附件只有2个!钱是10的整数倍,不是100的整数倍! #include <cstdio> #include <cstring> #include &l ...

  8. B1051 受欢迎的牛 tarjan缩点

    就是一道tarjan缩点的板子,之前在洛谷做过.但是我发现一个事,就是函数里面有一句话: void tarjan(int x) { dfn[x] = low[x] = ++tot; str[++top ...

  9. 动态规划---区间dp

    今天写内网题,连着写了两道区间dp,这里就总结一下. 区间dp思想主要是先枚举f[i][j]中的i,再枚举j,再枚举一个1~j之间的变量k,一般是f[i][j] = max(f[i][j],f[i][ ...

  10. Java -JVM:JVM百科

    ylbtech-Java -JVM:JVM百科 JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机 ...