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编辑  收藏  举报

导航