1.面向过程与面向对象

# 面向过程

面向过程,核心是在过程二字。面向过程设计思维,就好比精心设计好一条流水线,考虑周全,相应时候处理相应问题。

#%%
def test(x,y):
if x > y:
return x
elif x < y:
return y
return x + y

优点:将复杂的问题流程化,进而简单化。

缺点:扩展性差(如果更改需求,可能整个代码都需要重写,牵一发而动全身)

如果你写一些程序,去解决一些 简单的、固定性、不需要更新迭代的问题,使用面向过程的方式是比较好的。

如果你要处理的任务是复杂的,且需要不断更新迭代和维护的,使用面向对象方式是比较推荐的。

# 面向对象

面向对象,是对现实世界的模拟。

面向对象的编程特点:

1.可以编写表示真实世界中的事物和情景的类,并基于这些类来创建对象。

2.可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率。

简单介绍面向对象三大特点:

1.封装性

2.继承性

3.多态性

1.封装性

将对象的特征与行为保存起来。

2.继承性

通过继承,子类可快速获取父类特征与行为。

3.多态性

不同的子类对象,调用相同的父类方法,产生不同的执行结果。

#%%
class A:
def print_code(self):
print('hello lemon')
def func(func_class):
func_class.print_code()
class B(A):
pass
func(B())

运行结果:

hello lemon

#%%
def func2(object):
print(object.__len__())
func2('hello lemon')

运行结果:11

#%%

func2([1,2,3])

运行结果:3

#%%

2.创建一个简单的类# 在面向对象的编程中

# 我们可以编写表示真实世界中的事物和情景的类,并基于这些类来创建对象。
# 类:是描述具有相同的特征和行为的对象的集合
# 我们通过变量,可以去刻画类的特征。
# 我们通过方法,可以去描述类的行为。
# 如何去创建一个简单类
class 类名():
变量 # 刻画类的特征
def 相关方法名(self,相关参数): # 描述类的行为
pass
class Men():
gender = 'male'
avg_height = 1.7
def think(self):
print('thinking')
def sleep(self):
print('sleeping')
# 注意:类可以去定义,但不负责去执行相关方法

3.SELF与实例方法

# 如何让类生成一个对象
class Men():
gender = 'male'
avg_height = 1.7
def think(self):
print('thinking')
def sleep(self):
print('sleeping')
men = Men()

# 对于self进行说明

# 1.self名称是约定成俗的

# 2.self指向的是类实例化后的对象本身

# 3.self只有在类的方法中才会有,函数是不必带有self的

# 4.self在定义类的方法(实例方法)时是必须有的

# 5.self在调用时不必传入相应的参数。

# 实例方法

# 类实例化后的对象,能够使用的方法

#%%
class Men():
gender = 'male'
avg_height = 1.7
def sleep(self): # 实例方法
print('sleeping')
def think(self): # 实例方法
print('thinking')
men = Men()
men.sleep()
men.think()

运行结果:

sleeping

thinking

# 在调用方法的时不必手动传入self

4.__init__构造函数

# 类像是一个模板,通过类实例化,可以生成一个或多个对象

1.类:

类是描述具有相同的特征和行为的对象的集合。

特点:特征 与 行为

2.对象

类实例化后,可生成一个或多个对象。

#%%
class Men():
gender = 'male'
avg_height = 1.7
def sleep(self):
print('sleeping')
def think(self):
print('thinking')
xiaoming = Men()
xiaopeng = Men()
xiaohei = Men()
print(xiaoming.gender)
print(xiaopeng.gender)
print(xiaohei.gender)
print('----------')
print(xiaoming.avg_height)
print(xiaopeng.avg_height)
print(xiaohei.avg_height)

运行结果:

male

male

male

----------

1.7

1.7

1.7

# 问题:

# 1.生成的对象特征比较抽象,只具有类的通俗特征,没有描述对象的具体特征

# 使用构造函数,可让模板生成不同特征的对象

# 构造函数(通俗的叫法)

#%%
class Men():
gender = 'male'
avg_height = 1.7
def __init__(self,name,age):
# 初始化对象的特征
print('this is __init__')
self.name = name
self.age = age
def sleep(self):
print('sleeping')
def think(self):
print('thinking')
men = Men('lemon',18)
运行结果:
this is __init__
men.name
'lemon'
#%%
men.age
18
#%%
men.__dict__
{'name': 'lemon', 'age': 18}

# 通过 __dict__ 方法,可查看对象的具体特征

# 使用 构造函数好处:

# 1.初始化对象的特征

# 2.保存了对象的特征

5.通过实例方法访问实例变量与类变量

# 我们通过变量,可以去刻画类的特征。

# 我们通过方法,可以去描述类的行为。

# 类变量: 刻画类本身的特征 (只与类有关)

# 实例变量: 刻画对象的具体特征 (只与对象有关,这里的对象指的是实例化之后的对象)

#%%
class Men():
gender = 'male' # 类变量(描述类的通俗特征)
avg_height = 1.7
def __init__(self,name,age):
# 初始化对象特征
# 保存了对象的特征
self.name = name # 实例变量 (保存对象的具体特征)
self.age = age
def sleep(self):
print('sleeping')
def think(self):
print('thinking')
men = Men('lemon',18)
#%%
class Men():
gender = 'male' # 类变量
avg_height = 1.7
def __init__(self,name,age):
# 初始化对象特征
self.name = name # 实例变量
self.age = age
def sleep(self):
print('sleeping')
def think(self):
print('thinking')
def find(self):
print('this is ' + str(self.name))
print('I am ' + str(self.age))
print('--------------------')
print(self.__class__.gender)
print(self.__class__.avg_height)
print('--------------------')
print(Men.gender)
print(Men.avg_height)
print('--------------------')
print(self.gender)
print(self.avg_height)
men = Men('lemon',18)
men.find()
this is lemon
I am 18
--------------------
male
1.7
--------------------
male
1.7
--------------------
male
1.7


6.类方法

class Men():
gender = 'male'
avg_height = 1.7
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self): # 实例方法
print('sleeping')
def think(self):
print('thinking')
@classmethod
def modify_height(cls,height):
cls.avg_height += height
print('Success.Now the avg_height is ' + str(cls.avg_height))
Men.modify_height(-0.05)
运行结果:
Success.Now the avg_height is 1.75
#%%
Men.__dict__
mappingproxy({'__module__': '__main__',
'gender': 'male',
'avg_height': 1.75,
'__init__': ,
'sleep': ,
'think': ,
'modify_height': ,
'__dict__': ,
'__weakref__': ,
'__doc__': None})
# 开闭原则
# 对于扩展是开放的,对于修改是关闭的
# 疑问:如果平均身高上升0.05,那如何修改类变量的值

7.静态方法

class Men():
gender = 'male'
avg_height = 1.7
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self): # 实例方法
print('sleeping')
def think(self):
print('thinking')
@classmethod
def modify_height(cls,height): # 类方法
cls.avg_height += height
print('Success.Now the avg_height is ' + str(cls.avg_height))
# 静态方法,与普通函数基本上没有什么区别。
# 静态方法与类、对象没有太大关系的时候,可以使用该方法。
class Men():
gender = 'male'
avg_height = 1.7
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self): # 实例方法
print('sleeping')
def think(self):
print('thinking')
@classmethod
def modify_height(cls,height): # 类方法
cls.avg_height += height
print('Success.Now the avg_height is ' + str(cls.avg_height))
@staticmethod
def plus_num(x,y):
return x * y
men = Men('lemon',18)
men.plus_num(2,3)
运行结果:6
# 相对于静态方法,我更建议大家使用类方法

8.成员可见性

public 公开性 (外部可以访问相关变量 或 外部可以调用相关方法)
private 私有性 (外部不可以访问相关变量 或 外部不可以调用相关方法)
#%%
class Men():
gender = 'male'
avg_height = 1.7
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self): # 实例方法
print('sleeping')
def think(self):
print('thinking')
@classmethod
def modify_height(cls,height): # 类方法
cls.avg_height += height
print('Success.Now the avg_height is ' + str(cls.avg_height))
@staticmethod
def plus_num(x,y): # 静态方法
return x * y
men = Men('lemon',18)
men.name # 该变量具有公开性
运行结果:
'lemon'
men.think() # 该方法具有公开性
运行结果:
thinking
# 疑问:如何将变量或方法设置为私有性
#%%
class Men():
gender = 'male'
avg_height = 1.7
def __init__(self,name,age):
self.name = name
self.__age = age # 私有变量
def sleep(self): # 实例方法
print('sleeping')
def __think(self): # 私有方法
print('thinking')
@classmethod
def modify_height(cls,height): # 类方法
cls.avg_height += height
print('Success.Now the avg_height is ' + str(cls.avg_height))
@staticmethod
def plus_num(x,y): # 静态方法
return x * y
men = Men('lemon',18)
men.age
运行报错:
AttributeError Traceback (most recent call last)
 in () ----> 1men.age
AttributeError: 'Men' object has no attribute 'age'
men.__age
运行结果:
AttributeError Traceback (most recent call last)
 in () ----> 1men.__age
AttributeError: 'Men' object has no attribute '__age'
men.think()
运行结果:
AttributeError Traceback (most recent call last)
 in () ----> 1men.think()
AttributeError: 'Men' object has no attribute 'think'
men.__think()
运行结果:
AttributeError Traceback (most recent call last)
 in () ----> 1men.__think()
AttributeError: 'Men' object has no attribute '__think'
# 扩展:如何去修改实例变量的值
class Men():
gender = 'male'
avg_height = 1.7
def __init__(self,name,age):
self.name = name
self.age = age
self.salary = 0
def modify_salary(self,salary):
self.salary = salary
def sleep(self): # 实例方法
print('sleeping')
def think(self):
print('thinking')
@classmethod
def modify_height(cls,height): # 类方法
cls.avg_height += height
print('Success.Now the avg_height is ' + str(cls.avg_height))
@staticmethod
def plus_num(x,y): # 静态方法
return x * y
men = Men('lemon',18)
men.salary = 10 # 不建议
men.__dict__
运行结果:
{'name': 'lemon', 'age': 18, 'salary': 10}
men.modify_salary(20)
men.__dict__
运行结果:
{'name': 'lemon', 'age': 18, 'salary': 20}
9.PYTHON没有什么是不能访问的
#%%
class Men():
gender = 'male'
avg_height = 1.7 # 类变量
def __init__(self,name,age):
self.name = name # 实例变量
self.__age = age # 私有变量
def sleep(self): # 实例方法
print('sleeping')
def __think(self): # 私有方法
print('thinking')
@classmethod
def modify_height(cls,height): # 类方法
cls.avg_height += height
print('Success.Now the avg_height is ' + str(cls.avg_height))
@staticmethod
def plus_num(x,y): # 静态方法
return x * y
men = Men('lemon',18)
men.__age
运行结果:
AttributeError Traceback (most recent call last)
 in () ----> 1men.__age
AttributeError: 'Men' object has no attribute '__age'
men.__think()
运行结果:
AttributeError Traceback (most recent call last)
 in () ----> 1men.__think()
AttributeError: 'Men' object has no attribute '__think'
men.__dict__
运行结果:
{'name': 'lemon', '_Men__age': 18}
men._Men__age
运行结果:18
men._Men__think()
运行结果:thinking

10.继承

# 继承
# 通过继承,子类可直接使用父类的功能,减少重复代码。
#%%
class Men(): # 父类 或 基类
gender = 'male'
avg_height = 1.7
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self):
print('sleeping')
def think(self):
print('thinking')
# 需求:
# 1.创建一个 ChineseMen 类,这个类 与 Men这个类的特征与行为相同
class ChineseMen(Men): # 子类
pass
xiaoming = ChineseMen('xiaoming',18)
xiaoming.__dict__
运行结果:
{'name': 'xiaoming', 'age': 18}
xiaoming.sleep()
运行结果:sleeping
xiaoming.think()
运行结果:thinking
# 疑问:那如果我想对某些功能进行进一步扩展,那该如何?
# 扩展功能:
# 1.除了想保存具体对象的姓名,年龄,还想保存对象的身高
# 2.sleep 方法,更改为 print(self.name + ' is sleeping')
# 通过继承,子类可扩展父类的相关功能,增加代码的灵活性。
class Men(): # 父类 或 基类
gender = 'male'
avg_height = 1.7
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self):
print('sleeping')
def think(self):
print('thinking')
# 继承特点:
# 1.通过继承,子类可直接使用父类的功能,减少重复代码。
# 2.通过继承,子类可扩展父类的相关功能,增加代码的灵活性。
# 扩展功能:
# 1.除了想保存具体对象的姓名,年龄,还想保存对象的身高
# 2.sleep 方法,更改为 print(self.name + ' is sleeping')
#%%
class ChineseMen(Men): # 子类
def __init__(self,name,age,height):
Men.__init__(self,name,age)
self.height = height
def sleep(self):
Men.sleep(self)
print(self.name + ' is sleeping')
# 问题:
# 1.用一个类来调用实例方法,本身说不通,也不好理解;
xiaoming = ChineseMen('xiaoming',18,180)
xiaoming.__dict__
运行结果:
{'name': 'xiaoming', 'age': 18, 'height': 180}
xiaoming.sleep()
运行结果:
sleeping
xiaoming is sleeping

11.SUPER关键字调用父类方法class Men(): # 父类 或 基类

gender = 'male'
avg_height = 1.7
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self):
print('sleeping')
def think(self):
print('thinking')
class ChineseMen(Men):
def __init__(self,name,age,height):
self.height = height
Men.__init__(self,name,age)
def sleep(self):
Men.sleep(self)
print(self.name + ' is sleeping')
# 问题:
# 1.用一个类来调用实例方法,本身说不通,也不好理解;
# 2.如果父类名字修改,那继承该父类的所有子类里面的名称都需要修改;
from IPython.display import Image
Image(filename = '继承.png')
# super 不仅能调用父类构造函数,也可调用父类实例方法。
# super 可以解决父类名称频繁变化的问题
#%%
class ChineseMen(Men):
def __init__(self,name,age,height):
self.height = height
super(ChineseMen,self).__init__(name,age)
def sleep(self):
super(ChineseMen,self).sleep()
print(self.name + ' is sleeping')
xiaoming = ChineseMen('xiaoming',18,180)
xiaoming.__dict__
运行结果:
{'height': 180, 'name': 'xiaoming', 'age': 18}
xiaoming.sleep()
运行结果:
sleeping
xiaoming is sleeping
# 其他需要注意的:
# 1.父类必须在子类前面
# 2.子类可继承一个或多个父类,但前期建议大家还是先继承一个父类