python面向对象

文章目录


B站课程 【Python】零基础入门——面向对象编程(强烈推荐)学习思考和记录吧。 参考博客

1.基本理论-课程介绍

本节就是介绍了此课程的知识框架
基本理论

  • 什么是对象?

    • 概念定义
    • 在Python中的体现
  • 面向过程&面向对象

    • 两种编程思想的对比,以及他们的侧重点
    • 如何从面向过程的编程过渡到面向对象的编程?
    • 面向对象编程的技巧
    • 类的概念,作用以及组成
    • 生活中类的案例映射
    • 对象和类的关系

面向对象在Python中的实现

  • 怎样定义一个类?
  • 怎样通过类,实例化一个对象
  • 属性相关
    • 如何增删改查对象属性&类属性
    • 二者直接的对比及内存存储差异
    • 属性的高级操作(限定,权限控制。。。)
  • 方法相关
    • 如何操作实例方法:类方法,静态方法?
    • 这几种类型的方法对比和使用场景
    • 重难点讲解
    • 方法的私有化
  • 元类(补充)

Python对象的生命周期,以及周期方法
面向对象编程-综合案例
面向对象三大特性

  • 封装
  • 继承
  • 多态
  • 每个特性所延展出来的技术点
    三大特性-综合案例
    常用设计模式
    单例 工厂 。。。
    开发经验补充
  • 类的设计原则
  • 单一职责原则
  • 迪米特原则
  • 开闭原则
  • 命名规范
  • 类名
  • 方法名
  • 属性
  • 。。。

2.基本理论-对象的概念

本节介绍了对象的概念。
万物皆是对象。
对象可以理解为一个把多个属性和多个行为这些零散的东西封装称为一个整体
例如王二小就是一个对象,他拥有姓名年龄身高等多个属性,有走路吃饭放羊等多种行为
Python是一门特别彻底的面向对象编程的语言。
在Python中int,float,list,array均为对象类型,这一特点区别去其他语言

3.基本理论-面向过程&面向对象-编程思想

二者都是一种解决问题的思路(思想)
面向过程,在解决问题的时候关注的是解决问题的每一个步骤
面向对象,在解决问题的时候关注的是解决问题所需要的对象
可能这些在合作编程的时候面向对象就有它的优势了,组长确定需要的对象,组员分别完成各个对象,组员可以将自己所被分配的对象下面建立新的对象,可以让同事帮忙去编写这个新的对象等等

4.基本理论-面向过程&面向对象-对比

面向对象本身是对面向过程的封装
面向过程编程就是把一个任务划分为多个步骤,也就是多个过程
面向对象编程其实就是把这些划分好的过程进行分类,分别分配给各个对象,每个对象有响应的属性和行为

  • 举例出一个任务的具体实现步骤
  • 试图分离这些实现步骤中的功能代码块
  • 将这些功能代码块,划分到某一个对象中
  • 根据这个对象以及对应的行为,抽象出对应的类___设计类

5.基本理论-类的简介

类就是从我们需要的对象中抽象出来的,然后可以根据抽象的类,产生具体的对象
类就是由名称,属性和方法组成的。这些属性和方法都是抽象的概念,在产生对象之后对象才拥有具体的属性值和方法实现

6.面向对象在Python中的实现-定义类(最简单的经典类)

本节就是函数定义和类定义的一个对比

def run():
	pass

# 经典类(Money后面加小括号表示继承的意思,这里我们先暂时不管)
class Money:
	pass

# 新式类

7.面向对象在Python中的实现-根据类创建一个对象

可以看出Money即为一个类,one为一个对象

print(Money)
# 根据这个类,创建(实例化)一个对象
one = Money()
print(one)
----------------------------------------------------------------------------------
<class '__main__.Money'>
<__main__.Money object at 0x00000000000253E048>

8.面向对象在Python中的实现-创建对象时的底层运作-简述版

Money一方面是类名,一方面是一个变量名称

print(Money.__name__)
xxx = Money
print(xxx.__name)
-----------------------------------------------------------
Money
Money

请添加图片描述

print(one.__class__)
-------------------------------------------------------------------
<class '__main__.Money'>
即可知one是从Money类实例化出来的对象

9.面向对象在Python中的实现-属性和变量的区分及判定依据

变量时可以改变的量值,属性是属于某个对象的特征
属性只能通过对象来访问,而对象时通过变量名来引用的
变量根据所在位置有不同的访问权限
判定依据:是否存在宿主

10.面向对象在Python中的实现-对象属性-添加操作

两种方式

  1. 直接通过对象,动态添加——语法:对象.属性 = 值
  2. 通过类的初始化方法(构造方法)——__init__方法
    本节重点讨论第一种方式
# 1. 定义一个类
class Person:
	pass

# 2. 根据类,创建一个对象
p = Person()

# 3. 给p对象,增加一些属性
p.age = 18

# dict可以查看一个对象中所有属性
print(p.__dict__)
------------------
{'age':18}

请添加图片描述

11.面向对象在Python中的实现-对象属性-查询操作

查询一个对象中的属性及print(p.sex)即可,若sex不存在,则会报错
AttributeError: 'Person' object has no attribute 'sex'

12.面向对象在Python中的实现-对象属性-修改操作

同新增一个属性的语法一样,新增是创建一个指针指向一个值,修改是更改一个指针的指向

13.面向对象在Python中的实现-对象属性-删除操作

使用del p.sex类似语句即可

14.面向对象在Python中的实现-对象属性-注意事项

由同一类实例化的两个不同对象,不能相互访问其中的属性

15.面向对象在Python中的实现-类属性-增加属性-上

类也是对象,可以在类外面通过赋值的办法添加属性

class Money:
	pass
one=Money()
Money.count=1 #给类增加一个属性
print(Money.count)
print(Money.__dict__)

16.面向对象在Python中的实现-类属性-增加属性-下

直接在类内添加属性

class Money:
	age=28
    count=1
    num=666
    
one=Money()
print(Money.count)
print(Money.age)
print(Money.__dict__)

17.面向对象在Python中的实现-类属性-查询属性

当然可以通过类自身访问类属性,例如Money.count
也可以用通过对像访问类属性:优先从对像自身上查找属性,找到则结束,如果没有找到,根据class找到对象对应的类,到这个类里面查找。

print(one.age)
print(one.aount)

更改对象从属的类的话,相应可以查找到的属性也就更改了

class text:
    pass
one.__class__ = text#更改对象的类
print(one.age)#不能访问

18.面向对象在Python中的实现-类属性-修改属性

通过类名修改,但不能通过对象修改

class Money:
	age=28
    count=1
    num=666
    
Money.age=22
print(Money.age)

19.面向对象在Python中的实现-类属性-删除属性

del 类名.属性名,例如del Money.age
不能通过对象删除,del语句只能删除直系属性
类的属性的增、删、改只能通过类来访问,查询的时候可以通过对象和类来访问!

20.面向对象在Python中的实现-属性的内存存储

所有的对象属性都存储在该对象的dict属性里面,以一个字典的方式
类的dict属性是只读的,不可以被更改的

class Money:
	age=28
    count=1
    num=666
        
one=Money()
one.__dict__['age'] = 999#对象的__dict__可以被修改
print(one.age)

21.面向对象在Python中的实现-类属性被各个对象所共享

查看一个类的所有属性通过类名.__dict__来查看

class Money:
	age=28
    count=1
    num=666
        
one=Money()
two=Money()
print(one.age)
print(two.age)

22.面向对象在Python中的实现-类属性和对象属性总结对比

23.面向对象在Python中的实现-限制对象属性的添加__slots__

class Person:
    __slots__=['age']  #只有slots所限定的属性
    pass
p1 = Person()
p1.age = 18
p1.name = '小狗' #将报错

24.面向对象在Python中的实现-方法的讲解说明

25.面向对象在Python中的实现-方法的概念和作用

方法:描述一个目标的行为动作。比如描述一个人怎样吃,怎样喝。怎样玩…
和函数一样都是封装了一系列行为动作,都可以在被调用之后执行一系列行为动作
但是调用方式不同

class Persondef eat2(self):
        print(1)
        print(2)
        print(3)
p = Person()
p.eat2()

26.面向对象在Python中的实现-类、对象、类对象、实例对象、实例的叫法规范

类实例化得到对象(实例),二者都是对象,一个是类对象,一个是实例对象

27.面向对象在Python中的实现-方法的划分依据

划分依据:方法的第一个参数必须要接受的数据类型

  • 实例方法默认第一个参数需要接收到一个实例
  • 类方法默认第一个参数需要接收到一个类
  • 静态方法第一个参数啥也不默认接收

不管是哪一种方法,都是存储在类当中,不存储在实例当中

class Person:
	def eat2(self):
        print('这是一个实例方法',self)
    @classmethod
    def leifangfa(cls):
        print('这是一个类方法',cls)
    @staticmethod
    def jiangtaifanfa():
        print('这是一个静态方法')

不同类型方法的调用方式不同,不管怎么调,把握一个原则,不管是自己传递还是解释器帮我们处理;最终要保证不同类型的方法第一个参数收到的数据,是他们想要的类型

29.面向对象在Python中的实现-小节掌握说明

要掌握方法对应语法,不同类型方法的规则和调用。根据不同的问题, 自己决定,到底该设计怎样的方法来解决问题

30.面向对象在Python中的实现-实例方法

标准的调用方法:使用实例调用实例方法,不用手动调,解释器会把调用对象(实例)本身传递过去。如果实例方法没有接受任何参数则会报错。

class Person:
    def eat(self,food):#self可以是aa、bb 等,一般是self
        print('在吃饭',food)

p = Person()
p.eat('土豆')
#-------------------------------
class Person:
    def eat(): #报错,因为实例方法必第一个必须接收实例作为第一个参数
        print('在吃饭')

p.eat()

其他的的调用方法:使用类调用、间接调用,他们的本质就是直接找到函数本身来调用。

# 类调用
Person.eat(123, 'abc')

# 间接调用
func = Person.eat
func(123, 'abc')

31.面向对象在Python中的实现-类方法

可以通过类调用,也可以通过实例调用,调用时解释器会将类传入第一个参数

class Person:
    @classmethod #装饰器的作用:在保证原函数不变的情况下,直接给这个函数增加一些功能
    def leifangfa(cls,a):
        print("这是一个类方法" , a)
        
Person.leifangfa(123)

p = person()
p.leifangfa(666)

func = Person.leifangfa
func(111)

此外,如果使用一个延伸类调用,解释器会把这个延伸类传入第一个参数

class A(Person):
	pass
A.leifangfa(0)

32.面向对象在Python中的实现-静态方法

class Person:
    @staticmethod #装饰器的作用:在保证原函数不变的情况下,直接给这个函数增加一些功能
    def jingtai(cls):
        print("这是一个类方法")
        
Person.jingtai()

p = Person()
p.jingtai()

func = Person.jingtai
func()

33.面向对象在Python中的实现-不同类型的方法中访问不同属性的权限问题

class Person:
    age = 0
    def shilifangfa(self):
        print(self)
        print(self.age)
        print(self.num)
    @classmethod
    def leifangfa(cls):
        print(cls)
        print(cls.age)
        print(cls.num)   #不能通过类访问实例属性
    @staticmethod
    def jingtaifangfa():
        print(Person.age) #可以通过类访问类属性
P = person()
P.num = 10

34.面向对象在Python中的实现-补充-元类

元类是创建类对象的类 <class ‘type’> 元类所属的类还是元类

num = 1
print(num.__class__)  #输出int
%------------------------------------------
s = "abc"
print(s.__class__)   #输出str
%------------------------------------------
class Person:
	pass
p = Person()
print(p.__class__)  #输出Person
%------------------------------------------
print(int.__class__)  #输出type

35.面向对象在Python中的实现-补充-类对象的创建方式

除了使用class创建,也可以调用type函数创建

def run(self):
    print(self)
xxx = type("Dog",(),{"count":0,"run":run})
print(xxx)
print(xxx.__dict__)

d = xxx()   #不是d.Dog
print(d)
d.run()

36.面向对象在Python中的实现-补充-类对象创建时元类的查找机制

类的创建流程:

  • 检测类对象是否有明确的__mateclass__属性。

  • 检测父类中是否存在__mateclass__属性。

  • 检测模块中是否存在__mateclass__属性。

  • 通过内置的type这个元类来创建这个类对象。

#1模块的指定
__metaclass__ = xxx
#2
class Animal:
    pass
#3 Animal是Dog的父类
class Dog(Animal):
    pass
#4 类对象中有__mateclass__属性
class Dog:
    __metaclass__ = xxx
    pass

37.面向对象在Python中的实现-补充-类的描述(注释)

class Person:
    """
    关于这个类的描述,类的作用,类的构造函数等等;类属性的描述
    Attributes:
    	count: int 代表人的个数
    """
    count = 1
    def run(self, disance, step):
        """
        这个方法的作用效果
        :param distance:blahblah
        :param step:blahblah
        :return:
        """
        print("跑步")
        return  distance,step
help(Person)  #

38.面向对象在Python中的实现-补充-注释文档的生成

注释文档不包括源码,只包括函数名和它的描述,使用的是python内置模块
查看文档描述:python3 -m pydoc 模块名称
启动本地服务,浏览文档 :python3- m pydoc-p 666
生成指定模块html文件:python3 -m pydoc -w 模块名称

cd <代码路径>
python --help
python -m pydoc <文件名>      #
python -m pydoc -k <关键字>   #列出文件名中包含关键字的文件
python -m pydoc -p <端口号>   #指定一个未用的端口号
python -m pydoc -b           #自动指定端口号
python -m pydoc -w <文件名>   #在当前目录生成一个html文件

39.面向对象在Python中的实现-补充-私有化属性的概念和意义

概念:限定属性的访问的方法。

40.面向对象在Python中的实现-补充-访问权限测试区域划分

注意:python并没有真正的私有化支持,但是,可以使用下划线完成伪私有的效果。如_y、__z

41.面向对象在Python中的实现-补充-共有属性

1.共有属性可以通过

  1. 类的内部访问,也就是类的实例方法中
  2. 子类(延伸类)内部访问
  3. 模块其他位置访问
    1. 类访问(父类,派生类)
    2. 实例访问(父类实例,派生类实例)
  4. 跨模块访问
    1. import形式导入
    2. from 模块 import * 导入
class Animal:
    x = 10
    def test(self):
        print(Animal.x)
        print(self.x)
        pass
%----------------------
class Dog(Animal):
    def test2(self):
        print(Dog.x)
        print(self.x)
        pass

a = Animal()
a.test()		#类的内部访问,通过类内部定义的函数访问

d = Dog()
d.test2()		#延伸类的访问(通过延伸类内部定义的函数访问)

print(Animal.x)		#模块的其他部分
print(Dog.x)
print(a.x)
print(b.x)

import xxx              #模块的其他部分访问
print(xxx.a)
from xxx import *
print(a)

42.面向对象在Python中的实现-补充-受保护的属性

class Animal:
    _x = 10
    def test(self):
        print(Animal._x)
        print(self._x)
     pass
#--------------------
class Dog(Animal):
    def test2(self):
        print(Dog._x)
        print(self._x)
     pass

a = Animal()
a.test()		#类的内部访问

d = Dog()
d.test2()		#延伸类的访问

print(Animal._x)		#模块的其他部分,可以强行访问,有警告
print(Dog._x)
print(a._x)
print(b._x)

import xxx              #模块的其他部分访问,不可访问
print(xxx.a)
from xxx import *
print(a)

43.面向对象在Python中的实现-补充-私有属性

class Animal:
    __x = 10
    def test(self):         #定义一个实例方法
        print(Animal.__x)
        print(self.__x)
     pass

#--------------------

class Dog(Animal):
    def test2(self):
        print(Dog.__x)
        print(self.__x)
     pass

a = Animal()
a.test()		#类的内部访问,可以访问

d = Dog()
d.test2()		#延伸类的访问,不可以访问

print(Animal.__x)		# 模块的其他部分,不可访问
print(Dog.__x)
print(a.__x)
print(d.__x)

a = 1
import xxx              #模块的其他部分访问,不可访问
print(xxx.a)
from xxx import *
print(a)

44.面向对象在Python中的实现-补充-名字重整机制

class Animal:
    __x = 10
    def test(self):
        print(Animal.__x)
        print(self.__x)
        pass

print(Animal.__dict__)
print(Animal,_Animal__x)

45.面向对象在Python中的实现-补充-私有属性的应用场景

1.数据保护 2.数据过滤

class Person:
    #作用:当我们创建好一个实例对对象之后,会自动调用这个方法,来初始化这对象
    #init是单词初始化initialization的省略形式
    def __init__(self)
    	self.__age = 18
    def setAge(self,value):
        if isinstance(value,int) and 0<value<200:
        	self.__age = value
        else:
            print("您输入的数据有误,请重新输入")
    def getAge(self):
        return self.__age
    
        
p1 = Person()
p1.setAge(20)
p2 = Person()
print(p1.getAge())   #访问age

print(p1.__age)      #报错,只能在类内部访问
print(p2.__age)

46.面向对象在Python中的实现-补充-变量添加下划线的规范

xx_:避免与系统关键字冲突
__xx__:系统内置

47.面向对象在Python中的实现-补充-只读属性的概念和意义

只读属性的概念:一个属性只能读取,不能写入

48.面向对象在Python中的实现-补充-只读属性-方案一

class Person(object):
	def __init__(self):
		self.__age = 18

	def getAge(self):
		return self.__age
p1 = Person()
print(p1.getAge())

49.面向对象在Python中的实现-补充-只读属性-方案一的优化

class Person(object):
    def __init__(self):
        self.__age = 18
     # 主要作用:可以以使用属性的方法来使用这个方法
    @property
    def age(self):   #部分公开,通过方法实现
        return self.__age
p1 = person()
print(p1.age())

50.面向对象在Python中的实现-补充-property的作用

property的作用:将“一些属性的操作方法”关联到另一个属性,间接地管理私有属性。

class C(object):
    def getx(self): return self._x
    def setx(self,value): self._x = value
    def delx(self): del self._x
    x = property(getx, setx, delx)

51.面向对象在Python中的实现-补充-经典类和新式类

  1. 经典类:没有继承object
  2. 新式类:继承object
class Person:
    pass

print(Person.__bases__)  #查看父类(基类)k

在python2中,定义一个类,没有显式的继承自object,那么这个类就是一个经典类,显式的继承自object,他才是一个新式类。

在python3中,定义一个类,会隐式的继承object,所以默认情况下,就已经是一个新式类。

52.面向对象在Python中的实现-补充-property在新式类中的使用

property函数方法

class Person(object):
    def __init__(self):
        self.__age = 18
    def get_age(self):
        ruturn self.__age
    def set_age(self, value):
        self.__age = value
    age = property(get_age, set_age)
    
p = Person()
print(p.age)

p.age = 30
print(p.age)
print(p.__dict__) #输出只有_person__age: 

装饰器的方式

 class Person(object):
    def __init__(self):
        self.__age = 18
           @property
           def age(self):
               return self.__age
           @age.setter
           def age(self, value):
               delf.__age = value

    p = Person()
    p.age = 20    #既可以读取也可以设置

53.面向对象在Python中的实现-补充-property在经典类中的使用(切换版版本为python2)

没学,现在都是python3

54.面向对象在Python中的实现-补充-只读属性-方案二

虽然是私有属性,任然可以通过两种方法设置__age属性:

p._Person__age=xxx

p.__dict__['_Person__age']=xxx

 class Person:
    #当我们通过实例.属性 = 值,给一个实力增加一个属性,或者修改属性的时候,就会自动调用这个方法,
    #在这个方法内部才会正真地把这个属性,以及对应的数据存储到__dict__字典里面
    def __setattr__(self, key, value):
        print(key, value)
        #1.判定,key,是否是我们要设置的只读属性
        if key == "age" and key in self.__dict__.keys():#只能新增属性,不能修改属性
           print("这个属性是只读属性,不能设置数据")
        #2.如果不是只读属性,就给他添加到实例里面去
        else:
           #self.key = value  #这样会陷入死循环
           self.__dict__[key] = value

55.面向对象在Python中的实现-补充-常用内置属性

  1. 类属性:
    __dict__:类属性
    __bases__:类的所有父类构成元组
    __doc__:类的文档字符
    __name__:类名
    __module__:类定义所在模块
  2. 实例属性:
    __dict__:类的实例
    __class__:实例对应的类

56.面向对象在Python中的实现-补充-私有方法

方法:在函数名前加两个下划线,与属性私有化相同,名字重整机制是相同的。

class Person:
    def __run(self):
        print("run")
p = Person()
print(Person.__dict__)

57.面向对象在Python中的实现-补充-内置特殊方法-使用意义

内置方法的作用;完成一些特定的功能

58.面向对象在Python中的实现-补充-内置特殊方法-initstr

给初始化方法__init__里边传递参数,即可创建不同的对象

class Person:
    def __init__(self,n,a):
        self.name = n
        self.age = a
p1 = Person("zpc", 18) #可创建不同的对象

通过定义__str__,就可以通过print(<对象>)来查看指定的返回值

class Person:
    def __init__(self,n,a):
        self.name = n
        self.age = a
    def __str__(self):
        return "这个人的姓名是%s,这个人的年龄是%s"%(self.name, self.age)
p1 = Person("zpc",18) #可创建不同的对象

s=str(p1)
print(s)

59.面向对象在Python中的实现-补充-内置特殊方法-repr

__repr__面向的对象是开发人员(解释器);__str__面向的对象是用户。

def Person:
    def __init__(self):
        return"repr"

如果没有定义__str__,那么str也返回的是__repr__的内容
触发__str__的方法:

  1. 直接打印:print(p1)
  2. str方法:s=str(p1) print(s)
    触发__repr__的方法:
  3. s=repr(p1) print(s)
  4. 在交互模式里面将对象名称写出,敲回车

60.面向对象在Python中的实现-补充-内置特殊方法-call-概念和作用

__call__的作用:使得对象具有当作函数来调用的能力(将对象变为可调用对象)

class Person:
    def __call__(self):
        print("xxx")
    pass
p = Person()
p()            #调用__call__函数

61.面向对象在Python中的实现-补充-内置特殊方法-__call__应用场景的简单案例

使用functools.partial

def createPen(p_color, p_type):
	print("创建了一个%s类型的画笔,他是%s颜色的"%(p_type, p_color))

import functools

gangbiFunc = functools.partial(createPen, p_type="钢笔")

gangbiFunc("黄色")
gangbiFunc("绿色")
gangbiFunc("红色")

使用面向对象思路
首先创建一个类,类的属性只有一个(p_type),然后创建一个__call__方法(只接收一个参数p_color),这样就可以通过<实例>(p_color)

class PenFactory:
    def __init__(self, p_type):
        self.p_type = p_type       #这个类只有一个属性
    def __call__(self, p_color):
        print("创建了一个%s类型的画笔,他是%s颜色的"%(self.p_type, p_color))
gangbiF = penFactory("钢笔")       #创建一个对象
gangbiF('红色')

62-python-面向对象-索引操作(使对象具有像字典一样的索引操作)

1.以索引的方式操作python序列:

  1. 增、改:p[1] = 666、p[‘name’] = sz
  2. 查:p[name]、p[1]
  3. 删除:del p[name]、del p[1]
    2.需要一个字典属性,才可以对对象进行索引操作。
class Person:
    def __init__(self):
        self.cache = {}              #定义cache属性,为一个字典
    def __setitem__(self, key, value):
        self.cache[key] = value
    def __getitem__(self, key):
        return self.cache[key]
    def __delitem__(self, key):
        del self.cache[key]
p = Person()
p['name'] = 'sz'  #执行这行代码的时候,会调用第一个方法
print(p['name'])  #调用第二个方法

63-python-面向对象-切片操作

  1. 索引是对一个进行增、删、改、查;切片是对多个进行增、删、改、查。

  2. python3中,‘切片操作’统一由‘索引操作’进行管理!

    1. def __setitem__(self, key, value):
    2. def __getitem__(self, item):
    3. def __delitem__(self, key):
class Person:
    def __init__(self):
        self.items = [1, 2, 3, 4, 5, 6, 7, 8]  #定义了一个items属性
        
    def __setitem__(self, key, value):
        if isinstance(key,silce):
        self.items[key] = value           #注意切片操作只能修改,不能新增
        #self.items.[key.start: key.stop: key.step] = value  #这样赋值也可以
    def __getitem__(self, key):
        return(key.items[key])            #这里可能有错
    def __delitem__(self, key):
        del self[key]
p = Person()
p[0: 4: 2] = ["a","b"]
print(p.items[0: 4: 2])

64-python-面向对象-比较操作-映射的内置方法

为对象定义比较操作,调用此方法,就可以使对象可以向数一样比较大小!

class Person:
    def __init__(self, age, height):
        self.age = age
        self.height = height
    def __eq__(self, other):
        return self.age == other.age   #指定相等的比较通过哪个属性比较,
    def __ne__(self, other):
        return self.age != other.age   #指定相等的比较通过哪个属性比较,
p1 = Person(18, 180)
p2 = Person(19, 183)
print(p1 == p2)
#类似的还有:
#gt >
#ge >=
#lt <
#le <=  
#可以通过调换参数的方式定义比较方法,进而简化代码

65-python-面向对象-比较操作-注意事项

如果对于反向操作的比较符, 只定义了其中一个方法
但使用的是另外一种比较运算
那么, 解释器会采用调换参数的方式进行调用该方法

  • 定义了 “小于” 操作 x < y
  • 使用 x > y 会被调换参数, 调用上面的 “小于操作”

但是, 不支持叠加操作

  • 定义了 “小于” 和 “等于” 操作
  • 不能使用 x <= y

66-面向对象-比较操作-方案2(通过装饰器自动补全)

import functools

@functools.total_ordering      #此装饰器会自动补全所需要的方法
class Person 
    def __lt__(self, other):
        pass
    def __eq__(self, other):
        pass

67-python-面向对象-比较操作-上下文布尔值

  1. 非空即为True
  2. 此方法使对象可以被作为一个布尔值使用。
class Person():
    def __bool__(self):    #通过bool值判定实例是True或False
        return False       #这里也可以是一个返回布尔值的语句
    pass

p = Person()
if p:
    print("xx")

68-python-面向对象-遍历操作-__getitem__

让我们创建的对象可以使用for循环进行遍历

class Person:
    def __init__(self):
        self.result = 1
    def __getitem__(self, item):
        self.result += 1
        if self.result >=6:   #不满足时,跳出循环
            raise StopIteration("停止遍历")
            
        return relf.result
    pass
p = person()

for i in p:    #当执行for循环时,自动进入__getitem__方法,使用这个方法的返回值作为数据
    print(i)

69-python-面向对象-遍历操作-__iter__

__iter__的优先级高于__getitem__

class Person:
    def __init__(self):
        self.result = 1
    def __getitem__(self, item):
        self.result += 1
        if self.result >=6:   #不满足时,跳出循环
            raise StopIteration("停止遍历")
            
        return relf.result
    def __iter__(self):
        print("hfkjasdf")
p = person()

for i in p:    #当执行for循环时,自动进入__geritem__方法,使用这个方法的返回值作为数据
    print(i)

可迭代对象包含迭代器。
如果一个对象拥有__iter__方法,其是可迭代对象;如果一个对象拥有__next__方法,其是迭代器。
定义可迭代对象,必须实现__iter__方法;定义迭代器,必须实现__iter____next__方法。
首先调用__iter__,返回一个迭代器,然后调用__next__方法;

class Person:
    def __init__(self):
        self.result = 1
    def __getitem__(self, item):
        self.result += 1
        if self.result >=6:   #不满足时,跳出循环
            raise StopIteration("停止遍历")
        #return iter([1,2,3,4])    如果返回是迭代器,则自动进入迭代器的__next__方法   
        return relf.result
    def __iter__(self):
        return self
    def __next__(self):
        self.result += 1
        if self.result >=6:   #不满足时,跳出循环
            raise StopIteration("停止遍历")    
        return relf.result
p = person()

for i in p:    
    print(i)

70-python-面向对象-遍历操作-__next__

通过next函数访问迭代器,能通过next访问的不一定是迭代器,没有__iter__也可以访问

class Person:
    def __init__(self):
        self.result = 1
    def __getitem__(self, item):
        self.result += 1
        if self.result >=6:   #不满足时,跳出循环
            raise StopIteration("停止遍历")
        #return iter([1,2,3,4])    如果返回是迭代器,则自动进入迭代器的__next__方法   
        return relf.result
    
    def __next__(self):
        self.result += 1
        if self.result >=6:   #不满足时,跳出循环
            raise StopIteration("停止遍历")    
        return relf.result
p = person()

print(next(p))   #直接进入__next__方法
print(next(p))
print(next(p))
print(next(p))
print(next(p))   #抛出异常,停止遍历

71-python-面向对像-遍历操作-迭代器的复用

class Person:
    def __init__(self):
        self.age = 1
        
    def __iter__(self):
        self.age = 1   # 如果没有这行命令,那么迭代器只能使用一次
        return self
    
    def __next__(self):
        self.age += 1
        if self.age >=6:   #不满足时,跳出循环
            raise StopIteration("停止遍历")    
        return relf.age
    
p = person()
for i in p:
    print(i)
import collection
print(isinstance(p, collection.Iterator))  
#返回值为True,表明确实是一个迭代器,需要同时有两个方法__iter__、__next__
next(p)  #只要有一个方法__next__就可以访问

72-python-面向对象-遍历操作-迭代器-可迭代的判定依据

一个可迭代对象一定可以通过for in访问,可以通过for in访问的不一定是可迭代对象

import collection
print(isinstance(p, collection.Iterable))#判定是否为可迭代对象,只要一个方法__iter__就可以 

73-python-面向对象-遍历操作-iter的使用

  1. 通过next()函数访问对象,要想让iter()对创建的对象起作用,需要在类里边定义方法:__getitem__或者:__iter____next__(这两个方法必须同时都需要)。
    还有def __call__(self, *args, **kwargs):
  2. iter(<要转换的对象>,<停止数值>)

74-面向对象-描述器-概念和作用

概念和作用:描述器是一个对象,可以描述一个属性的操作;其作用是对属性的操作做验证和过滤,如对一个人的年龄赋值时,不能赋值为负数,这是需要验证和过滤,但由于属性数量多,不能在赋值前进行验证,所以用到描述器,每次验证时就会进入描述器中进行相关操作

75-python-面向对象-描述器-定义方式1-property

class Person:
    def __init__(self):
        self.__age = 10
        
    @property
    def age(self):
        return self.__age
    
    @age.setter
    def age(self, value):
        if value < 0:
            value = 0
        self.__age = value
        
    @age.deleter
    def age(self):
        del self.__age
        
        
p = Person()
p.age             #注意:这里的age是方法里面的age,不是属性的age
del p.age

76-python-面向对象-描述器-定义方式2

对方式一进行优化,即多个属性时,由于操作内容不同,在主类中代码会过于繁琐,为简化代码,将属性的操作方法封装到类中,在主类中对方法类的实例对象进行操作即可

class Age:        #描述器类
    def __get__(self, instance, owner):
        print("get")
    def __set__(self, instance, value):
        print("set")
    def __delete__(self, instance):
        print("delete")
        
class Person:     #主类
    age = Age()   
    
p = Person()
p.age = 10
print(p.age)
del p.age

77-python-面向对象-描述器-调用细节1

不通过Person类调用age属性,只能通过Person类定义的对象来调用age属性。就是按上节的方式调用

78-python-面向对象-描述器-调用细节2

经典类中描述器无效,Person、Age必须全是新式类

79-python-面向对象-描述器-调用细节3

在这里插入图片描述

80-python-面向对象-描述器-调用优先级

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值