学习python第18天
一.面向对象编程
面向过程编程与面向对象编程
1.面向过程编程:
核心是过程2字,过程指的是做事的步骤,即先干啥,在干啥,后干啥
基于该思想编写程序就好比在设计一条条的流水线
优点:复杂的问题流程化,简单化
缺点:扩展性差
2.面向对象编程:
核心是对象2字,对象就是一个用来盛放相关数据与功能的容器
优点:程序耦合强,扩展性高
缺点:比面向过程更复杂
对象是数据与功能的集合体,而类则是对象之间相同数据与功能的集合体
对象1:
#学生1的数据
name = 'egon'
age = 18
gender = 'male'
对象2:
#学生2的数据
name = '王三炮'
age = 19
gender = 'female'
对象3:
#学生3的数据
name = '李大炮'
age = 20
gender = 'male'
学生类
#学生对象相同的数据
school = '上海校区'
# 学生对象相同的功能
选课功能
类与对象
1.在程序中必须先定义类:是申请内存空间,把对象之间相同的数据与功能存起来
类在定义时就会立即执行类体代码,会产生类的名称空间,然后类名指向该名称空间
class Student:
# 学生对象相同的数据
school = '上海校区'
# 学生对象相同的功能
def choose_course(self):
print('正在选课')
# print('<=====>') # 在调用之前运行一下我们会发现这行代码运行了
# print(Student.__dict__)
2.然后调用类来产生对象,调用类的过程又称之为实例化
调用类的本质:就是产生一个与类相关联的子空间
选课案例:
class Student:
school = "上海校区"
def choose_course(self):
print('正在选课')
stu1 = Student()
stu2 = Student()
stu3 = Student()
# print(stu1.__dict__) # ==>{}
# print(stu2.__dict__) # ==>{}
# print(stu3.__dict__) # ==>{}
# 非常麻烦的写法
# stu1.__dict__['name'] = 'egon'
# stu1.__dict__['age'] = 18
# stu1.__dict__['gender'] = 'male'
# 可以这样写
stu1.name = 'egon'
stu1.age = 18
stu1.gender = 'male'
stu2.name = '王三炮'
stu2.age = 19
stu2.gender = 'female'
stu3.name = '李大炮'
stu3.age = 20
stu3.gender = 'male'
# print(stu1.__dict__) #{'name': 'egon', 'age': 18, 'gender': 'male'}
# print(stu2.__dict__) #{'name': '王三炮', 'age': 19, 'gender': 'female'}
# print(stu3.__dict__) #{'name': '李大炮', 'age': 20, 'gender': 'male'}
# print(stu1.name) # egon
# print(stu1.age) # 18
# print(stu1.gender) # male
# print(stu1.school) # 上海校区
# print(stu1.choose_course) # 会打印绑定的方法选课功能的内存地址
def func(stu1):
print(stu1.name)
print(stu1.age)
print(stu1.gender)
print(stu1.school)
print(stu1.choose_course)
二. __init__方法
选课案例改进1:
class Student:
school = '上海校区'
def choose_course(self):
print('正在选课')
stu1 = Student()
stu2 = Student()
stu3 = Student()
def init(obj,x,y,z):
obj.name = x
obj.age = y
obj.gender = z
init(stu1,'egon',18,'male')
init(stu2,'王三炮',19,'female')
init(stu3,'李大炮',20,'male')
print(stu1.__dict__) #{'name': 'egon', 'age': 18, 'gender': 'male'}
print(stu2.__dict__) #{'name': '王三炮', 'age': 19, 'gender': 'female'}
print(stu3.__dict__) #{'name': '李大炮', 'age': 20, 'gender': 'male'}
选课案例改进2:
class Student:
school = '上海校区'
# 空对象,'egon',18,'male'
def __init__(self,x,y,z):
self.name = x # 空对象.name='egon'
self.age = y # 空对象.age=18
self.gender = z # 空对象.gender='male'
print('======>')
#该函数内可以有任意代码,但是该函数不能返回非None值
# return 123 报错 不能返回非None值
def choose_course(self):
print('%s 正在选课' %self.name)
def func(self,x,y):
print(self.name,x,y)
#调用类
# 1.会先创造一个与类相关联的子空间,也就是对象=>空对象
# 2.自动触发类内__init__(空对象,'egon',18,'male')
# 3.返回一个初始化好的对象,我们可以赋值给一个变量名
stu1 = Student('egon',18,'male')
stu2 = Student('王三炮',19,'female')
stu3 = Student('李大炮',20,'male')
类属性操作:
类与对象都可以通过 . 来访问属性完成增删改查的操作
class Student:
school = "上海校区"
def __init__(self, x, y, z):
self.name = x
self.age = y
self.gender = z
def choose_course(self):
print('%s 正在选课' %self.name)
def func(self,x,y):
print(self.name,x,y)
stu1 = Student("egon",18,"male")
stu2 = Student("王三炮",19,"female")
stu3 = Student("李大炮",20,"male")
print(Student.__dict__)
#1.访问类的数据属性
# Student.school='xxx'
# print(Student.school) # xxx
# Student.xxx = 111 # 在类空间增加数据
# print(Student.__dict__)
# del Student.xxx # 在类空间删除数据
# print(Student.__dict__)
#2.访问类的函数属性:它就是一个普通函数,该传几个参数就传几个参数
print(Student.choose_course)
Student.choose_course(stu1) #egon 正在选课
Student.choose_course(stu2) #王三炮 正在选课
Student.choose_course(stu3) #李大炮 正在选课
对象属性操作:
对象.属性,会先从对象自己的空间里找,没有的话去类中找
class Student:
school = "上海校区"
def __init__(self, x, y, z):
self.name = x
self.age = y
self.gender = z
def choose_course(self):
print('%s 正在选课' %self.name)
def func(self,x,y):
print(self.name,x,y)
stu1 = Student("egon",18,"male")
stu2 = Student("王三炮",19,"female")
stu3 = Student("李大炮",20,"male")
# 1.类中定义的数据属性为了给对象用的,而且所有对象共享的,大家访问的都是同一个地址
# print(id(Student.school)) # 1678873462128
# print(id(stu1.school)) # 1678873462128
# print(id(stu2.school)) # 1678873462128
# print(id(stu3.school)) # 1678873462128
#
# Student.school = 'XXX' # 修改类的数据属性,所有对象都会跟着改
# print(stu1.school) # XXX
# print(stu2.school) # XXX
# print(stu3.school) # XXX
stu1.school='YYY' # 只是在stu1这个子空间做了增加操作
print(stu1.__dict__) # {'name': 'egon', 'age': 18, 'gender': 'male', 'school': 'YYY'}
print(stu1.school) # YYY
print(Student.school) #上海校区
print(stu2.school) #上海校区
print(stu3.school) #上海校区
# 2.类中的定义的函数属性,类可以调用但就是一个普通函数,而类中函数通常都是为对象
# 准备的,也就是说是给对象用的,如何给对象用? 绑定给对象
print(Student.choose_course)
print(stu1.choose_course)
stu1.choose_course() #choose_course(stu1) =>egon 正在选课
stu2.choose_course() #choose_course(stu2) =>王三炮 正在选课
stu3.choose_course() #choose_course(stu3) =>李大炮 正在选课
三.内置函数
1.eval():用来执行一个字符串表达式,并返回表达式的值
dic = {'k1':111}
with open('a.txt',mode='wt',encoding='utf-8')as f:
f.write(str(dic))
with open('a.txt',mode='rt',encoding='utf-8')as f:
line=f.read() #line="{'k1':111}"
# print(type(line))
line=eval(line)
print(line['k1'])
2.frozenset():返回一个冻结的集合,冻结后集合不能再添加或删除任何元素
s = frozenset({1,2,3})
print(s)
3.pow():计算x的y次方,如果z存在,则再对结果进行取模,其结果等于pow(x,y) %z
print(pow(x,y,z))
print(pow(10,3,3)) # 10 ** 3 % 3
4.reversed():返回一个反转的序列
l = [111,'aaa',333]
res = reversed(l) #res是一个迭代器
for x in res:
print(x)
l=list(reversed(l)) # 将迭代器中的值一个个添加进列表
print(l)
5.round():返回浮点数x的四舍五入值,小数点后一位小于等于5舍去,大于5进1
print(round(x))
print(round(4.6)) #5
print(round(4.7)) #5
print(round(4.4)) #4
print(round(4.5)) #4
6.slice():实现切片对象,主要用在切片操作函数里的参数传递(了解)
s=slice(0,5,2)
print(l[0:5:2]) # 0 2 4
print(l[s]) # 0 2 4
msg="hello world"
print(msg[s])
7.sorted():排序
l = [444,111,222,555,666,333,777,888]
new_l=sorted(l)
print(new_l)
dic = {
'zegon':3000,
'lxx':2000,
'axx':4000
}
res = sorted(dic,key=lambda x:dic[x],reverse=True)
print(res) #['axx', 'zegon', 'lxx']
8.sum():计算总和
print(sum([1,2,3,4]))
9.zip():
用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
# msg='hello'
msg={'name':'egon'}
l=[111,222,333]
res=zip(msg,l)
print(list(res)) # [('name', 111)]