Python 全栈开发:python初识面向对象
一、面向对象
面向过程编程
核心是”过程“二字,过程指的是解决问题的步骤,即先干什么再干什么
基于该思想编写程序就好比在编写一条流水线,是一种机械式的思维方式
优点:复杂的问题流程化、进而简单化
缺点:可扩展性差
优点:解决程序的扩展性,可扩展性强
缺点:1.编程的复杂度高于面向过程
2.可控性差,无法像面向过程一样精准的预测问题的处理流程与结果
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方
二、类和对象
对象是特征与技能的结合体,那类就是一系列对象相同的特征与技能的结合体
类:具有相同属性特征的一类事物
对象:具体的某一事物
在现实世界中:先有对象,再有类
在程序中:务必保证:先定义类,后调用类来产生对象
程序中模板
#1. 在程序中特征用变量标识,技能用函数标识
#2. 因而类中最常见的无非是:变量和函数的定义
#3. 在定义类的阶段会立刻执行类体内的代码,然后将产生的名字存放于类名称空间中
#4. __init__ 不能有返回值
class 类名: def __init__(self,参数1,参数2): self.对象的属性1 = 参数1 self.对象的属性2 = 参数2 def 方法名(self):pass def 方法名2(self):pass 对象名 = 类名(1,2) #对象就是实例,代表一个具体的东西 #类名() : 类名+括号就是实例化一个类,相当于调用了__init__方法 #括号里传参数,参数不需要传self,其他与init中的形参一一对应 #结果返回一个对象 对象名.对象的属性1 #查看对象的属性,直接用 对象名.属性名 即可 对象名.方法名() #调用类中的方法,直接用 对象名.方法名() 即可
注意点:
- 类中可以有任意python代码,这些代码在类定义阶段便会执行
- 因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过 类名.__dict__查看
- 对于经典类来说我们可以通过该字典操作类名称空间的名字(新式类有限制),但python为我们提供专门的.语法
- 点是访问属性的语法,类中定义的名字,都是类的属性
python为类内置的特殊属性
类名.__name__# 类的名字(字符串) 类名.__doc__# 类的文档字符串 类名.__base__# 类的第一个父类(在讲继承时会讲) 类名.__bases__# 类所有父类构成的元组(在讲继承时会讲) 类名.__dict__# 类的字典属性 类名.__module__# 类定义所在的模块 类名.__class__# 实例对应的类(仅新式类中)
python类定义阶段,每一个类的方法必须显示定义self
ps:def __init__(self): 这句话可以写也可以不写,只要有参数参进来的时候就必须得写
def 方法名(self):这里的self必须得写
三、类的实例化、对象的操作
类实例化:调用类产生对象的过程称为类的实例化,实例化的结果是一个对象,或称为一个实例
# 定义一个People类 class People: def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def run(self): print('%s is running' %self.name)
# 实例化一个对象 obj obj = People('fixd',18,'male')
实例化做的三件事:
- 先产生一个空对象
- 自动触发类内部的__init__函数的执行
- 将空对象,以及调用类括号内传入的参数,一同传给__init__,为对象定制独有的属性
查看对象的名称空间(__dict__)
print(obj.__dict__)
四、对象的操作
print(obj.name) #查看 属性name的值
obj.education='哈佛' # 添加属性
del obj.name # 删除属性
obj.age=19 # 修改属性值
print(obj.__dict__) # 查看实例化对象的名称空间
五、对象属性的查找顺序
先找对象自己的名称空间----------->>类的名称空间
1、类的数据属性:是给对象用的,而且直接共享给所有对象的用的,内存地址都一样
# 定义一个People类 class People: country = 'China' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def run(self): print('%s is running' % self.name) people1 = People('fixd01', 18, 'male') people2 = People('fixd02', 25, 'male') people3 = People('fixd03', 30, 'male') # 实例化三个对象 people1 = People('fixd01',18,'male') people2 = People('fixd02',25,'male') people3 = People('fixd03',30,'male') # 查看country属性对应的 内存地址 print(id(People.country)) print(id(people1.country)) print(id(people2.country)) print(id(people2.country)) ############################## #结果:id 值都是相同的 #140238495738936 #140238495738936 #140238495738936 #140238495738936
2、类的函数属性:是给对象调用,但是绑定给对象的用的,绑定到不同的对象就是不同的绑定方法
# 定义一个People类 class People: country = 'China' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def run(self): print('%s is running' % self.name) # 实例化三个对象 people1 = People('fixd01', 18, 'male') people2 = People('fixd02', 25, 'male') people3 = People('fixd03', 30, 'male') # 调用 run()方法 people1.run() people2.run() people3.run() # 查看run 的内存地址 print(people1.run) print(people2.run) print(people3.run) # ############################## #结果: 内存地址不同 fixd01 is running fixd02 is running fixd03 is running ############################## #结果: 内存地址不同 <bound method People.run of <__main__.People object at 0x7f1c487e3978>> <bound method People.run of <__main__.People object at 0x7f1c487e39e8>> <bound method People.run of <__main__.People object at 0x7f1c487e3a20>>
六、绑定方法的特殊之处
- 绑定给谁就应该由谁来调用
- 谁来调用就会把谁当做第一个参数传入
七、一切皆对象
在python3中统一了类与类型的概念,类即类型。