一切皆对象
关于类与对象操作的BIFs自带电池(重要)
type() 返回对象类型
id(),memoryview(),查看对象id和内存地址
dir(),查看对象下变量及函数
help(),帮助
issubclass(),isinstance()子类,实例操作
hasattr(),getattr(),setattr(),delattr()对象属性操作
globals(),locals(),全局与局部的名称空间
import(),reload(),模块的导入与重载
序列:len(),range(),zip(),map(),reduce(),filter(),reversed(),sorted(),enumerate()
面向对象OOP
面向过程:根据业务逻辑从上到下写垒代码
函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
面向对象:对函数进行分类和封装,让开发“更快更好更强…”
面向过程编程容易理解,其往往用一长段代码来实现指定功能。
函数是对面向过程的一次封装
面向对象是更高一层的封装
类
类与对象
类:从近似的对象中抽象出类
类(class)的变量是所有对象共享使用, 只有一个拷贝, 所有对象修改, 都可以被其他对象所见;
对象:然后再从类出实例化出对象
对象(object)的变量由类的每个对象所拥有,每个对象都包含自己的一份拷贝, 不会影响其他对象;
好比a这个变量其实是整形数字int类的一个实例
int这个类还可以’复刻’出许许多多的整形对象。
这些对象共有的特征就是:整数性。
类的创建
□创建类
□ class class 关键字
□ 指定继承
□ 定义类的成员
□ 数据成员
■ 类变量
■ 实例变量
□ 方法成员
■ 类方法
■ 实例变量
类的内部结构
□ 数据成员 :[用于处理类及实例对象的相关数据 用于处理类及实例对象的相关数据 用于处理类及实例对象的相关数据 用于处理类及实例对象的相关数据 ]
□ 类变量 :在类中且函数体外 在类中且函数体外 ,实例之间共享 实例之间共享 实例之间共享
□ 实例变量 :定义在方法中 ,作用于当前实例的类 作用于当前实例的类 作用于当前实例的类 作用于当前实例的类
□ 方法成员 (在类中定义的函数叫方法 在类中定义的函数叫方法 在类中定义的函数叫方法 ) :
□ 类方法
■ 定义时需要使用 @classmethod装饰器 ,第一个参数为cls
□ 实例方法
■ 绑定到实例的方法 ,第一个参数为self,
□ 静态方法 [普通方法 ]
■ 定义的时候使用 @staticmethod装饰器 。
■ 静态方法没有参数限制 ,不需要实例参数self和类参数 cls
■ 静态法可以通过类名访问 ,也可以通过实例访问。
案例
#完成一个学生类的设计
#要求能查看总学生人数,全部学生姓名,毕业分数标准1000,已经毕业学员数量。
#实现考试方法,成绩分数如果大于60分代表其通过考试,分数计入该学员总分。
#如果该学员累计分数达到1000分,该学员即毕业
#实现查分方法,向该学员返回是否已经毕业,或者还差多少分数才能毕业
#实现查询所有已毕业学生数量的功能
#实现查询所有学生数量的功能
#实现查询所有学生姓名的功能
##数据成员
class Student(): #类变量 共性的
student_total=0
student_list=[]
student_graduated=0
pass_score=1000
def __init__(self,name,age,gender): #实例变量 初始化实例自身的 第一个必须是self,
self.name=name
self.age=age
self.gender=gender
self.__score=0 #属性非常重要 被保护了
Student.student_total+=1
Student.student_list.append(name)
##方法成员
def exam(self,score): #加了self的就是实例方法
if score<60:
return 'sorry, You have failed this time,better luck next time'
else:
self.__score+=score
str1='Good!, Your score is now'+str(self.__score)
if self.__score>=Student.pass_score:
Student.student_graduated+=1
return str1
def check(self,):
if self.score<Student.pass_score:
return 'You have',Student.pass_score-self.score,' scores to archive!'
else:
return 'You have graduated from julyedu.com'
@classmethod #类方法 一定要用这个装饰器
def get_student_graduated(cls,): #cls是指向类的指针,第一个形参要命名为cls.
return Student.student_graduated
@classmethod
def get_student_list(cls,):
return Student.student_list
@staticmethod #静态方法
def static1():
return 'this is a static method from Student, it can be called by both the instance and the class'
xiaohong=Student('xiaohong',23,'female')
xiaoming=Student('xiaoming',22,'male')
xiaoming.exam(99)
__score就是访问控制,python通过命名约定来实现访问控制
□对模块级的控制 ,通过在标识符前加单下划线 通过在标识符前加单下划线 通过在标识符前加单下划线 通过在标识符前加单下划线 _实现 。
□ 对类内部的属性及方法 ,通过在标识符前加双 通过在标识符前加双 通过在标识符前加双 通过在标识符前加双 下划线 __来实现的私有化。
类的继承与多态
一个类可以以 class newclsname():来开始全新构造(实际上会默认继承自object);
也可以从某个已经存在的类继承。.
继承的类叫做subclass。
多态的概念是应用于Java和C#这一类强类型语言中,
Python是弱类型语言,Python崇尚“鸭子类型”
在Python世界中,一切都是对象
##继承
#比如要构造蜘蛛这个类,可以从昆虫这个类继承。
#构建学生,雇员,战士都可以从人这个类继承。
class person():
def speak(self,): #实例方法
return 'people can speak language!'
def work(self,):
print('people should have work to do!')
class fireMan(person): #继承
def work(self,):
print('A great work that can save people!')
def speak2(self,):
print(super().speak(),'FireMan needs to speak loudly!') #super是父类
class employee(person): #继承
def work(self,):
print('To gain profits for the company is our job!')
# 因为类具有继承关系,子类可以向上转型被看做是父类的类型,比如无论是战士还是快递员,都是人类。
# 也因为有了继承关系,子类可以继承父类的所有方法和属性
#当然也可以重载父类的成员函数及属性。
#例如,当子类(直升机)和父类(飞机)都存在相同的fly()方法时,子类的fly()覆盖了父类的fly()
#在运行时就总是会调用子类的fly()。这就是继承带来的多态。
fireman1=fireMan()
fireman1.work() ##多态
fireman1.speak2() #super方法调用父类
employee1=employee()
employee1.work() #子类的
魔术方法
魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现 (重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被python所调用,你可以定义自己想要的行为 ,这些会自动发生 。
它们经常是两个下划线包围来命名的
- 比较魔术
# __cmp__(self, other) __cmp__ 是最基本的用于比较的魔术方法。
#它实际上实现了所有的比较符号(<,==,!=,etc.),
#但是它的表现并不会总是如你所愿(比如,当一个实例与另一个实例相等是通过一个规则来判断,
#而一个实例大于另外一个实例是通过另外一个规则来判断)。
#如果 self < other 的话 __cmp__ 应该返回一个负数,当 self == other 的时候会返回0 ,而当 self > other 的时候会返回正数。
#通常最好的一种方式是去分别定义每一个比较符号而不是一次性将他们都定义。
#但是 __cmp__ 方法是你想要实现所有的比较符号而一个保持清楚明白的一个好的方法。
# __eq__(self, other) 定义了等号的行为, == 。
# __ne__(self, other) 定义了不等号的行为, != 。
# __lt__(self, other) 定义了小于号的行为, < 。
# __gt__(self, other) 定义了大于等于号的行为, >= 。
#示例
class myclass():
def __init__(self,num):
self.num=num
print('被__init__')
def __del__(self,):
print('被__del__')
def __eq__(self,other):
if type(other)==int:
return True if self.num>other else False
else:
print('can\'t compare with other datatype except int',)
c1=myclass(3)
c1=='china'
- 数值处理魔法
# __pos__(self) 实现正号的特性(比如 +some_object)
# __neg__(self) 实现负号的特性(比如 -some_object)
# __abs__(self) 实现内置 abs() 函数的特性。
# __invert__(self) 实现 ~ 符号的特性。
# __add__(self, other) 实现加法。
# __sub__(self, other) 实现减法。
# __mul__(self, other) 实现乘法。
# __floordiv__(self, other) 实现 // 符号实现的整数除法。
# __div__(self, other) 实现 / 符号实现的除法。
# __truediv__(self, other) 实现真除法。
#__iadd__(self, other) 实现赋值加法+=
class myclass():
def __init__(self,num):
self.num=num
print('被__init__')
def __neg__(self):
self.num=2
c1=myclass(-3)
-c1
c1.num
#如果不执行-c1 输出的是-3 ,一旦类变成负的,返回的是2
- 类表现魔法
- 容器魔法
- 反射
- 调用
模块与包
模块定义:一个.py文件,包含了对象定义与语句
模块的作用:用来逻辑上组织代码
模块的使用:
1.搜索路径
搜索路径设置(修改sys.path ,sys.path.append() ,设置环境变量)
2.导入方法
import test #作为模块导入
from *** import *** #指定模块下具体的类或者对象,导入当前空间
包定义:含有__init__.py文件夹被成为包,init.py文件用于识别当前文件夹是一个包。包用于组织模块,通常把功能相近的模块进行再次封装成包
包的目录结构:
模块
子包
子包下的子包
包的安装、导入与访问
包的安装(pip,conda)
不同的导入方式(假设包名为test)
import test #导入__init__.py这个模块
from test import *
OOP三大特性总结
封装
封装就是将抽象的数据(变量)和行为(函数)打包,形成一个逻辑上的整体(即类);
封装可以增强安全性(数据)并简化编程(函数),用户只能通过类对外接口的访问权限来使用类的成员。
继承
一个类可以以 class newclsname():来开始全新构造(实际上会默认继承自object);
也可以从某个已经存在的类继承。继承的类叫做subclass。
比如要构造蜘蛛这个类,可以从昆虫这个类继承。构建学生,雇员,战士都可以从人这个类继承。
多态
因为类具有继承关系,子类可以向上转型被看做是父类的类型,比如无论是战士还是快递员,都是人类。
也因为有了继承关系,子类可以继承父类的所有方法和属性,
当然也可以重载父类的成员函数及属性。例如,当子类(直升机)和父类(飞机)都存在相同的fly()方法时,
子类的fly()覆盖了父类的fly(),在运行时就总是会调用子类的fly()。这就是继承带来的多态。