PYTHON 基础-DAY7/8 20210410

  • 面向对象(Object Oriented Programming,OOP)编程:扩展性更强、可读性更好。面向对象的编程将数据和操作数据封装到对象中,组织代码和数据的方式更接近人的思维,提高编程效率。
  • python支持面向对象、面向过程、函数式编程等多种编程范式

086-087 面向对象和面向过程的区别

面向过程procedure oriented思维

  • 面向过程编程:“程序的逻辑流程”,适合编写小范围的程序。

面向对象object oriented思维

  • 面向对象编程:“软件中对象之间的关系”,适合编写大规模的程序
  • 思考方式:名词—类—根据需求确定属性和方法—确定之间关系

对象的进化

  • 简单数据-数组-结构体-对象<结构体与对象的差别:结构体中存在处理数据的方法>

088-094 类

类的定义

  • 类:也称为类对象,类的实例称为实例对象
    -语法:
class 类名:
	类体

-类名符合标识符规则:首字母大写,驼峰规则
-类体中可以定义属性和方法
-属性用来描述数据,方法(即函数)来描述数据相关的操作
-init()方法:初始化创建好的对象,初始化指“给实例属性赋值”
-new()方法:用于创建对象,但一般无需定义该方法

class GoodStudent:
	def __init__(self,name,score): #self必须位于第一个参数
		self.name=name
		self.score=score
	def say_score(self):
		print("{0}的分数是:{1}".format(self.name,self.score))
s1=GoodStudent("hzh",18). #调用构造方法
s1.say_score()

构造函数__init__()

  • python对象包含三部分:id(identity识别码)、type(对象类型)、value(对象的值,包括属性attribute、方法method)
  • 创建对象后,需要定义构造函数__init__()方法,用于执行“实例对象的初始化工作”,即对象创建后,初始化当前对象的相关属性,无返回值。
  • 要点:
    -名称固定,必须为__init__()
    -第一个参数固定,必须为self #self指刚创建好的实例对象
    -构造函数通常用来初始化实例对象的实例属性
    -通过“类型(参数列表)”调用构造函数。调用后,将创建好的对象返回相应的变量
    -init()方法:初始化创建好的对象,初始化指“给实例属性赋值”
    -new()方法:用于创建对象,但一般无需定义该方法

实例属性

  • 实例属性:从属于实例对象的属性,即实例变量
    -实例属性一般在__int__()方法中通过如下代码进行定义 :self.实例属性名=初始值
    -在本类的其他实例方法中,通过self进行访问:self.实例属性名
    -创建实例对象后,通过实例对象访问:
    obj01=类名() #创建对象,调用__init__()初始化属性
    obj01.实例属性名=值 #给已有属性赋值或者添加新属性

实例方法

  • 实例方法:从属于实例对象的方法。
#实例方法的定义格式
def 方法名(self[,形参列表]):
	函数体

#实例方法的调用格式
对象.方法名([实参列表])
  • 要点
    -定义实例方法时,第一个参数必须是self,self值当前的实例对象
    -调用实例方法时,不需要也不能给self传参,self由解释器自动传参。
  • 函数和方法的区别
    -本质相同,都是为了完成一个功能的语句块
    -方法是通过对象进行调用,方法从属于特定实例对象,普通函数没有该特点。
    -直观上,方法定义需要传递self,函数不需要。
  • 实例对象的方法调用本质:a=Student() a.say_score() —> Student.say_score()<解释器翻译>
  • 其他操作:
    -dir(obj):可以获取对象的所有属性、方法
    -obj.dict:对象的属性字典
    -pass:空语句
    -isinstance(对象,类型):判断对象是不是指定类型

类对象

  • 当解释器执行class语句时,会创建一个类对象

类属性和类方法

  • 类属性“从属于类对象的属性,也称为“类变量”。类属性从属于类对象,因此可以被实例对象共享。类属性的定义方式:
class 类名:
	类变量=初始值
  • 类属性可通过“类名.类变量名”进行读取,内存分析:在这里插入图片描述
  • 类方法:从属于类对象的方法,通过装饰器@classmethod来定义
    -@classmethod必须位于方法上面一行
    -第一个cls必须写;cls指类对象本身
    -调用类方法格式:类名.类方法名(参数列表)。参数列表中,不需要/不能给cls传值
    -类方法中访问实例属性和实例方法会导致错误
    -子类继承父类方法是,传入cls是子类对象,而不是父类对象
@classmethod
def 类方法名(cls[,形参列表]):
	函数体
  • 静态方法:与“类对象”无关的方法。静态方法与普通模块的普通函数没有区别,只是静态方法放到了类名字空间里面,需要通过类调用。静态方法通过装饰器**@staticmethod**定义。
    -staticmethod必须位于方法上面一行
    -调用静态方法格式:类名.静态方法名(参数列表)
    -静态方法中访问实例属性和实例方法会导致错误
@staticmethod
def 静态方法名([形参列表]):
	函数体

095 __del__方法(析构函数)和垃圾回收机制

  • __del__方法:即析构方法,用于实现对象被销毁时所需的操作。
  • python实现自动的垃圾回收机制,当对象没有被引用时(引用计数为0),由垃圾回收器调用__del__方法。系统自动提供__del__方法,不需要自定义析构方法

096 __call__方法和可调用对象

  • 定义了__call__方法的对象,称为可调用对象,即对象可以像函数一样被调用
class SalaryAccount:
	def __call__(self,salary):
		print("工资")
		yearsalary=salary*12
		return dict(yearsalary=yearsalary)
a=SalaryAccount()
ptiny(a(3000)) #打印调用的__call__,输出字典

097 方法

  • 方法没有重载:即定义一个方法可以有多种调用方式,相当于实现了其他语言中方法的重载(多个重名的方法)。因此如果在类体中定义了多个重名的方法,只有最后一个方法有效。
    !不实用重名的方法,python中方法没有重载
  • 方法的动态性:python是动态语言,可将动态的类添加新的方法,或者动态的修改类的已有方法
#测试方法的动态性
class Person:
	def work(self):
		print("work hard!")
def play_game(s):
	print("{s} palys game".format(s))
def work2(s):
	print("studing hard!")
Person.play=play_game #添加新的方法
p=Person
p.work()
p.play()

Person.work=wprk2 #修改已有的方法
p.work

098-099 私有方法和私有属性:实现封装

  • python没有严格的访问控制限制,是与其他面向对象语言的区别。私有属性的和私有方法的要点:
    -两个下划线开头的属性是私有的private,其他为公共的public;
    -类内部可以访问私有属性(方法)
    -类外部不能直接访问私有属性(方法)
    -类外部可以通过“_类名_私有属性(方法)名”访问私有属性(方法)
    !方法本质也是属性,只不过是通过()执行。
#测试私有属性和私有方法
class Employee:
	__emotion="happy"
	def __init__(self,name,age):
		self.name=name
		self.__age=age #私有属性
	def __work(self):  #私有方法
		print("work hard!")
		#类内部调用私有属性
		print("{0}'s age is {2}".format(self.name,self.__age)) 
		#类内部调用私有类变量
		print(Employee.__emotion)
e=Employee("hzh",18)
print(e.name)
print(e._Employee__age) #print(e.age)则不能输出结果,因为age为私有属性

e._Employee__work() #调用私有方法
print(Employee._Employee__emotion)

100 @property 装饰器

  • @property:可以将一个方法的调用方式变成“属性调用”
#简单测试@property
class Employee:
	@property #将一个方法的调用方式变成“属性调用”
	def salary(self):
		print("salary run....")
		return 1000
emp1=Employee()
#emp1.salary()
print(emp1.salary)

#@property装饰器的用法
class Employee:
	def __init__(self,name,salary):
		self.__name=name
		self.__salary=salary
"""
	def get_salary(self):
		return self.__salary
	def set_salary(self,salary):
		if 1000<salary<50000:
			self.__salary=salary
		else:
			print("Error")

emp1=Employee('hzh',10000)
print(emp1.get_salary())
emp1,set_salary(-20000)
print(emp1.get_salary())
"""

	@property
	def salary(self):
	return self.__salary
	@salary.setter #针对salary的属性设置
	def salary(self,salary):
		if 1000<salary<50000:
			self.__salary=salary
		else:
			print("Error")
emp1=Employee('hzh',10000)
print(emp1.salary)		
emp1.salary=-2000
print(emp1.salary)

101-1 面向对象的三大特征介绍

  • python:是面向对象的语言,也支持面向对象编程的三大特征:继承、封装(隐藏)、多态
  • 封装(隐藏):隐藏对象的属性和实现细节,只需要对外提供必要的方法,通过私有属性私有方法的方式,实现封装。python没有严格的语法级别的“访问控制符”,通过自觉实现
  • 继承:让子类具有父类的特性,提高代码的重用性。一种增量进化,在原油父类设计不变情况下,可增加功能或改进已有算法。
  • 多态:同一种方法调用由于对象不同会产生不同的行为

102-108 继承

102 继承的定义与使用

  • 继承:实现“代码重用”重要手段,支持多重继承<一个字累可以继承多个子类>,语法格式:
    -如果类定义中没有指定父类,则默认父类是object类,即object是所有类的父类,定义了一些所有类共有的默认属性
    定义子类时,必须再起构造函数中调用父类的构造函数,即父类名.init(self,参数列表 )
#继承的定义
class 子类类名[父类1[,父类2,...]]
	类体
#测试继承的基本使用
class Person:
	def __init__(self,name,age):
		self.name=name
		self.__age=age. #私有属性
	def say_age(self):
		print("i don't know")
class Student(Person):
	def __init__(self,name,age,score):
		#必须显示调用父类初始化方法,不然解释器不回去调用
		Person,__init__(self,name,age)
		self.score=score
s=Student("hzh",20,90)
s.say_age()
print(s.name)
print(s._Person__age) #子类继承了私有属性,但是不能直接使用,若寻找可通过print(dir(s))寻找

103 类成员的继承和重写

  • 成员继承:子类继承父类构造函数之外的所有成员
  • 方法重写:子类可以重新定义父类中的方法,因此会覆盖父类的方法,叫做重写
class Person:
	def __init__(self,name,age):
		self.name=name
		self.__age=age. #私有属性
	def say_age(self):
		print(“my age:,self__age)
	def say_introduce(self):
		print("my name is {}".format(self.name))
class Student(Person):
	def __init__(self,name,age,score):
		#必须显示调用父类初始化方法,不然解释器不回去调用
		Person,__init__(self,name,age)
		self.score=score

	def say_introduce(self):
	'''重写方法,相当于覆盖了父类的方法'''
		print("Sorry,my name is {}".format(self.name))
s=Student("hzh",20,90)
s.say_age()
s.say_introduce()

104 查看类的继承结构、object根类

  • 通过类的方法mro()或者类的属性__mro__可以输出这个类的继承结构
class A:pass
class B(A):pass
class C(B):pass
print(C.mro()) #C->B->A->object
  • object类是所有类的父类,因此所有类都有object类的属性和方法
    -可通过内置函数dir()方法查看对象属性
    -object的所有属性,Person作为object子类,都包含所有的属性
    -实际上,实例方法也是属性,只不过属性的类型是“method”

105 重写__str__()方法

  • object有一个__str__()方法,用于返回对于“对象的描述”,经常使用print()方法,帮助查看兑现多个信息。str()可以重写
#测试__str__()
class Person:
	def __init__(self,name):
		self.name=name
	def __str__(self):
	‘’‘返回对象的描述信息‘’‘
		return("my name:{}".format(self.name))
p=Person("hzh")
print(p) #__str__()实现重写

106 多重继承

  • 多重继承:即一个子类有多个直接的父类,类的整体层次会变的复杂,尽量避免使用

107 mro()

  • python支持多重继承,如果父类中包括相同名字的方法,在子类没有指定父类名时,解释器将从左到右按顺序搜索。
  • MROmethod resolution order:方法解析顺序,可通过mro()方法获得类的层次结构,方法的解析也是通过“类的层次结构”寻找

108 super()获得父类的定义

  • super()获取的是父类的定义,而不是父类的对象,在子类中想获取父类的方法,可通过super()方法获取。
class A:
	def say(self):
		print("A:",self)
class B(A):
	def say(self)
		#a.say(self)
		super().say()
		print("b:",self)
B().say()

109 多态

  • 多态polymorphism:指同一种方法调用由于对象不同可能会产生不同的行为。
    -要点:多态是方法的多态,属性没有多态;多态的存在有2个必要条件(继承、方法重写)
class Man:
	def eat(self):
		print("None")
class Chinese(Man):
	def eat(self):
		print("chinese")
class English(Man):
	def eat(self):
		print("english")
def maneat(m):
	if isinstance(m,Man):
		m.eat()
	else:
		print("No One")
maneat(Chinese())
maneat(English())

110 特殊方法和运算符重载

  • python的运算实际上是通过调用对象的特殊方法实现。每个运算符都对应了相应的方法
    +:add
    -: sub
    <,<=,==: lt_le__eq_ >,>=,!=:gt_ge__nq_
    |,^,&:or_xor__and_
    <<,>>:lshift_rshift__
    *,/,%,//:mul_truediv__mod__floordiv_
    **:pow
  • 常见特殊方法
    init:构造方法 <对象创建p=Persopn()>
    del:析构方法 <对象回收>
    repr,str:打印、转换 <print(a)>
    call:函数调用 <a()>
    gatattr:点号运算 <a.xxx>
    setattr:属性赋值 <a.xxx=value>
    getitem:索引计算 <a[key]>
    setitem:索引赋值 <a[key]=value>
    len:长度 <len(a)>
#测试运算符的重载
class Person:
	def __init__(self,name):
		self.name=name
	def __and__(self,other):
		if isinstance(other,Person):
			return "{0}-{1}".format(self.name,other.name)
		else:
			renturn "error"
	def __mul__(self,other):
		if isinstance(other,int):
			return self.name*other
		else:
			return "error"
p1=Person("hzh")
p2=Person("terence")
x=p1+p2
print(x) #若未定义__add__则会报错
print(x*7)

111 特殊属性

  • obj.dict:对象的属性字典
  • obj.class:对象所属的类
  • class.bases:类的基类元组(多继承)
  • class.base:类的基类
  • class.mro:类的层次结构
  • class.subclasses():子类列表

112 对象的浅拷贝、深拷贝

  • 变量的赋值:形成两个变量,但实际还是指向同一对象
  • 浅拷贝:copy.copy()拷贝时,对象包含的子对象内容不拷贝,因此源对象和拷贝对象会引用同一子对象
  • 深拷贝:copy.deepcopy递归拷贝对象中包含的子对象,源对象和拷贝对象引用的子对象不同

113 组合

  • “is a”关系:可以使用继承,从而实现子类拥有父类的方法和属性
  • “has a”关系:可以使用组合,实现一个类拥有另一个类的方法和属性
#测试继承实现代码的复用
class A1:
	def say_a1(self):
		print("a1a1a1")
class B1(A1):
	pass
b=B1()
b.say_a1()

#测试组合实现代码的复用
class A2:
	def say_a2(self):
		print("a2a2a2")
class B2:
	def __init__(self,a):
		self.a=a
c=A2()
d=B2(C)
d.a.say_a2()

114-115 设计模式与设计方法

  • 设计模式:是面向对象语言的特有内容,是在面临某一类问题时固定的做法。流行的设计模式为GOF23种设计模式。<初学者主要是:工厂模式和单例模式>
  • 工厂模式:实现了创建者与调用者的分离,使用专门的工厂类将选择实现类、创建对象进行统一的管理和控制
  • 单例模式实现singleton pattern:核心作用确保一个类只有一个实例,并提供一个访问该实例的全局访问点。减少了系统资源的开销,当一个对象产生需要比较多的资源时可产生一个单例对象,然后永久驻留内存从而降低开销。

115 设计方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值