python基础知识--7面向过程与面向对象
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__': <function __main__.Men.__init__(self, name, age)>, 'sleep': <function __main__.Men.sleep(self)>, 'think': <function __main__.Men.think(self)>, 'modify_height': <classmethod at 0x104f4b7b8>, '__dict__': <attribute '__dict__' of 'Men' objects>, '__weakref__': <attribute '__weakref__' of 'Men' objects>, '__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)
<ipython-input-84-d7d486f5386f> in <module>() ----> 1 men.age
AttributeError: 'Men' object has no attribute 'age'
men.__age
运行结果:
AttributeError Traceback (most recent call last)
<ipython-input-85-29bd6f9c266e> in <module>() ----> 1 men.__age
AttributeError: 'Men' object has no attribute '__age'
men.think()
运行结果:
AttributeError Traceback (most recent call last)
<ipython-input-88-b8c70f9f5727> in <module>() ----> 1 men.think()
AttributeError: 'Men' object has no attribute 'think'
men.__think()
运行结果:
AttributeError Traceback (most recent call last)
<ipython-input-89-74da0f6ef9b5> in <module>() ----> 1 men.__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)
<ipython-input-4-29bd6f9c266e> in <module>() ----> 1 men.__age
AttributeError: 'Men' object has no attribute '__age'
men.__think()
运行结果:
AttributeError Traceback (most recent call last)
<ipython-input-5-74da0f6ef9b5> in <module>() ----> 1 men.__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.子类可继承一个或多个父类,但前期建议大家还是先继承一个父类
posted on 2020-10-23 00:26 kunlungege 阅读(139) 评论(0) 编辑 收藏 举报