一、引言
Python作为一门流行的编程语言,其前景一直是编程界的热门话题。Python简洁的语法、强大的标准库和丰富的第三方库使其在众多领域都有广泛的应用,从网站开发、数据分析、人工智能到科学计算等。随着数据科学和人工智能的兴起,Python的需求持续增长,成为了许多初学者和转行人士的首选语言。
根据业界调查,Python的流行度持续位于顶尖位置。技术发展的趋势表明,Python在未来仍然是一个值得投资学习的语言,不仅因为其在当前的技术市场中的需求,还因为它在教育、科研和自动化等领域的扩展性。
二、第十章
1.继承
# Author : zzd
# Date : 2016/3/21 10:01
# 继承
"""
父类:动物
子类:猫 、 狗 、 鸟继承动物的属性
如果一个类没有继承任何类,则默认继承Object
Python支持多继承
定义子类的时候,必须在其构造参数中调用父类的构造函数
"""
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def info(self):
print('姓名:{0},年龄:{1}'.format(self.name,self.age))
# 定义子类
class Student(Person):
def __init__(self,name,age,score):
super().__init__(name,age)
self.score = score
# 定义子类
class Teacher(Person):
def __init__(self,name,age,subject):
super().__init__(name,age)
self.subject = subject
# 测试
stu = Student('zxy',1,100)
stu.info()
2.封装
# Author : zzd
# Date : 2016/3/20 23:57
# 面向对象的三大特征:
"""
封装:提高程序的安全性
将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法
这样就无需关系内部的具体实现细节,从而降低复杂度
在Python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个"_"
继承:提高代码的复用性
多态:提高程序的可扩展性和可维护性
"""
# 封装
class Student:
def __init__(self,name,age):
self.name = name
## age前加两个下划线,表示不希望被类外使用
self.__age = age
def show(self):
print('name is ', self.name,'age is ',self.__age)
# 使用封装方法
try:
stu = Student('张三',20)
stu.show()
print(stu.name)
print(stu.age)
except AttributeError:
print("Error : 'Student' object has no attribute 'age'")
finally:
"""
尽管在类中,age属性被添加两个下划线来表示不可被外部调用
但是可以通过dir查看对象,发现_Student__age的属性
"""
print(dir(stu))
print(stu._Student__age)
3.多态
# Author : zzd
# Date : 2016/3/21 10:01
# 多态
"""
简单的说,多态就算“具有多种形态”,它指的是:
即使不知道一个变量所引用对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,
动态决定调用哪个对象中的方法
"""
# 静态语言和动态语言
# 静态语言如Java
# 动态语言如Python
"""
静态语言实现多态的三个必要条件:
1。继承
2.方法重写
3.父类引用指向子类对象
动态语言的多态崇尚“鸭子类型”,当看到一只鸟走路像鸭子,游泳像鸭子,收起来像鸭子,那么这只鸟就可以被称为鸭子。
在鸭子的类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为
"""
4.方法重写
# Author : zzd
# Date : 2016/3/21 10:01
# 方法重写
"""
如果子类对继承的父类的某个属性或方法不满意,可以在子类中对其进行重写编写
子类重写后的方法中可以通过super().方法名()调用父类中被重写的方法
"""
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def info(self):
print('姓名:{0},年龄:{1}'.format(self.name,self.age))
# 定义子类
class Student(Person):
def __init__(self,name,age,score):
super().__init__(name,age)
self.score = score
def info(self):
super().info()
print('成绩:{0}'.format(self.score))
# 定义子类
class Teacher(Person):
def __init__(self,name,age,subject):
super().__init__(name,age)
self.subject = subject
def info(self):
super().info()
print('学科:{0}'.format(self.subject))
# 测试
stu = Student('zxy',1,100)
stu.info()
tea = Teacher('Mr.zxy',2,'数学')
tea.info()
5.特殊属性
# Author : zzd
# Date : 2016/3/21 10:02
# 特殊方法和特殊属性
"""
特殊属性:
__dict__ : 获得对象或实例对象所绑定的所有属性和方法的字典
特殊方法:
__len__() : 通过重写__len__()方法,让内置函数len()的参数可以是自定义类型
__add__() : 通过重写__add__()方法,可以使用自定义对象具有'+'功能
__new__() : 用于创建对象
__init__() : 对创建的对象进行初始化
"""
class A(object):
pass
class B(object):
pass
class C(A,B):
def __init__(self,name,age):
self.name = name
self.age = age
c = C('zxy',1)
print(c.__dict__) # 实例对象c所有属性的字典
print(C.__dict__) # 类
print(c.__class__) # 输出对象所属类
print(C.__bases__) # 输出C类的父类元素
print(C.__base__) # 输出C类的第一个父类元素
print(C.__mro__) # 查看类的层次结构
print(A.__subclasses__()) # 查看A的子类
6.特殊方法
# Author : zzd
# Date : 2016/3/21 12:12
# 特殊方法和特殊属性
"""
特殊属性:
__dict__ : 获得对象或实例对象所绑定的所有属性和方法的字典
特殊方法:
__len__() : 通过重写__len__()方法,让内置函数len()的参数可以是自定义类型
__add__() : 通过重写__add__()方法,可以使用自定义对象具有'+'功能
__new__() : 用于创建对象
__init__() : 对创建的对象进行初始化
"""
# 测试__add__()
a = 20
b = 30
c = a + b
d = a.__add__(b) ## 调用a的对象__add__()方法
print(c)
print(d)
# __len__() : 通过重写__len__()方法,让内置函数len()的参数可以是自定义类型
# __add__() : 通过重写__add__()方法,可以使用自定义对象具有'+'功能
class Student():
def __init__(self,name):
self.name = name
def __add__(self, other):
return self.name + other.name
def __len__(self):
return len(self.name)
stu1 = Student('zzzz')
stu2 = Student('xx')
print('----------------------------__add__()------------------------')
stu3 = stu1 + stu2 # 重写__add__()方法
print(stu3)
print('----------------------------__len__()------------------------')
print(len(stu3))
# __new__() : 用于创建对象
# __init__() : 对创建的对象进行初始化
print('----------------------------__new__()-----__init__()-----------------------------------')
class Person():
def __new__(cls, *args, **kwargs):
print('cls的id为{0}',id(cls))
obj = super().__new__(cls)
print('创建对象ID为{0}'.format(id(obj)))
return obj
def __init__(self,name,age):
print('调用__init__(),self的ID值为{0}'.format(id(self)))
self.name = name
self.age = age
print('object类对象的ID为{0}'.format(id(object)))
print('Person类对象的ID为{0}'.format(id(Person)))
# 创建Person的实例对象
per = Person('zxy',1)
print('per这个实例对象的ID为{0}'.format(id(per)))
7.Object
# Author : zzd
# Date : 2016/3/21 10:01
# Object类
"""
1.Object类 是所有类的父类,因此所有类都有Object类的属性和方法
2.有内置函数dir()可以查看指定对象所有属性
3.Object有一个__str__()方法,用于返回一个对于“对象的描述”,
对于内置函数str()经常用于print()方法,帮我们查看对象的信息,
所以我们经常对__str__()进行重写
"""
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def info(self):
print('姓名:{0},年龄:{1}'.format(self.name,self.age))
def __str__(self):
return '姓名:{0},年龄:{1}'.format(self.name,self.age)
obj = object()
print(dir(obj))
per = Person('zxy',1)
print(dir(per))
print(per) # 重写str方法,用于返回对象的描述
8.类的浅拷贝和深拷贝
# Author : zzd
# Date : 2016/3/21 15:22
# 类的浅拷贝和深拷贝
"""
变量的赋值操作
只是形成两个变量,实际上还算指向同一个对象
浅拷贝:
Python拷贝一般是浅拷贝,拷贝时,对象包含的子对象内容不拷贝。
因此,源对象与拷贝对象会引用捅一个子对象。
深拷贝:
使用Copy模块的deepcopy函数,递归拷贝对象中包含的子对象,
源对象和拷贝对象所有的子对象也不相同
"""
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self,cpu,disk):
self.cpu = cpu
self.disk = disk
# 1.变量的赋值
cpu1 = CPU()
cpu2 = cpu1
print(cpu1,id(cpu1))
print(cpu2,id(cpu2))
# 2.浅拷贝
import copy
disk = Disk()
com = Computer(cpu1,disk)
com2 = copy.copy(com)
# 浅拷贝,由com复制到com2,发生变化,而子对象disk和cpu不发生变化
print(com,com.cpu,com.disk)
print(com2,com2.cpu,com2.disk)
# 3.深拷贝
com3 = copy.deepcopy(com)
# 深拷贝,由com复制到com3,源对象和子对象都被拷贝,从而发生变化
print(com,com.cpu,com.disk)
print(com3,com3.cpu,com3.disk)