python-面向对象编程
第八章 面向对象
用代码实现对列和栈
Queue队列:先进先出 FIFO(First In First Out)
Stack栈 : 后进先出 LIFO(Last In First Out)
-
方式一
class Foo:
def __init__(self):
self.l = []
def put(self,item):
self.l.apend(item)
class Queue(Foo):
def get(self):
return self.l.pop(0)
class Stack(Foo):
def get(self):
return self.l.pop()
obj = Queue()
obj.put(1)
obj.put(2)
print(obj.get())
print(obj.get()) # 先进先出
s1 = Stack()
s1.put(1)
s1.put(2)
print(s1.get()) # 先进后出
print(s1.get())
-
方式二
class Foo:
def __init__(self):
self.l = []
def put(self,item):
self.l.append(item)
def get(self):
return self.l.pop() if self.index else self.l.pop(0)
class Queue(Foo):
def __init(self):
self.index = 0
Foo.__init__(self)
class Stack(Foo):
def __init(self):
self.index = 1
Foo.__init__(self)
自定义Pickle,借助pickle模块来完成简化的dump和load
import pickle # 导入pickle模块
class My_pickle: # 定义pickle类
def __init__(self, path):
self.file = path
def dump(self, obj):
with open(self.file, 'ab') as f: # 以ab模式写入
pickle.dump(obj, f)
def load(self):
l = []
with open(self.file,'rb') as f: # rb模式读出
while True:
try:
l.append(pickle.load(f))
except EOFError:
break
return l
pic = My_pickle('pickle_file')
pic.dump(obj)
for i in pic.load():
print(i)
方式二
import pickle
class My_pickle:
def __init__(self,path):
self.file = path
def dump(self,obj):
with open(self.file,'ab') as f:
pickle.dump(obj,f)
def load(self):
with open(self.file,'rb') as f:
while 1:
try:
yield pickle load(f)
except EOFError:
break
pic = My_pickle('pickle_file')
pic.dump(obj)
for i in pic.load():
print(i)
自定义json
import json
class My_json: # 定义json类
def __init__(self, path): # 初始化方法
self.file = path
def dump(self, obj): # 方法
with open(self.file, 'a', encoding='utf-8') as f:
ret = json.dumps(obj)
f.write(ret + '\n')
def load(self):
with open(self.file, 'r', encoding='utf-8') as f:
while 1:
try:
for i in f:
yield json.loads(i.strip())
except EOFError:
break
obj = My_json('json_file') # 传入文件路径
obj.dump([1, 2, 3])
for i in obj.load():
print(i)
1. 面向对象基本格式
# ###### 定义类 ######
类的作用:1.实例化对象 2.操作静态变量
什么时候是对类中的变量赋值或使用:
类名.名字 = '值'
print(类名.名字) # print(对象名.名字) # 对象本身没有这个名字
什么时候是对对象中的变量赋值
对象名.名字 的时候和 self.名字
先来定义模子,用来描述一类事物
具有相同的属性和相似功能的一类
class 类名:
def 方法名(self,name):
print(name)
return 123
def 方法名(self,name):
print(name)
return 123
def 方法名(self,name):
print(name)
return 123
# ###### 调用类中的方法 ######
# 1.创建该类的对象
obj = 类名()
# 2.通过对象调用方法
result = obj.方法名('alex')
print(result)
# 类和对象之间的关系?
# 类 是一个大范围 是一个模子 它约束了事物有哪些属性 但是不能约束具体的值
# 对象 是一个具体的内容 是模子的产物 它遵循了类的约束 同时给属性赋上具体的值
# 写代码的时候,是先有的父类还是先有的子类?
# 在加载代码的过程中 需要先加载父类 所以父类写在前面
# 从思考的角度出发 总是先把子类都写完 发现重复的代码 再把重复的代码放到父类中
应用场景:复杂的 ,拥有开放式结局的程序, 比较适合使用面向对象开发,比如开发游戏(遇到很多函数,需要给函数进行归类和划分。 【封装】)
面向对象编程:是一类相似功能函数的集合,使你的代码更清晰化,更合理化。
什么时候用面向对象
-
函数(业务功能)比较多,可以使用面向对象来进行归类。
-
想要做数据封装(创建字典存储数据时,面向对象)。
-
游戏示例:创建一些角色并且根据角色需要再创建人物。
2. 面向对象的初识
class Person: # 类名
def __init__(self,name,sex,job,hp,weapon,ad):
# 必须叫__init__这个名字,不能改变的,所有的在一个具体的人物出现之后拥有的属性
self.name = name
self.sex = sex
self.job = job
self.level = 0
self.hp = hp
self.weapon = weapon
self.ad = ad
#
alex = Person('alex','不详','搓澡工',260,'搓澡巾',1) # alex 就是对象 alex = Person()的过程 是通过类获取一个对象的过程 - 实例化
print(alex,alex.__dict__)
wusir = Person('wusir','male','法师',500,'打狗棍',1000)
# print(wusir,wusir.__dict__)
print(alex.name) # print(alex.__dict__['name']) 属性的查看
alex.name = 'alexsb' # 属性的修改
print(alex.name)
alex.money = 1000000 # 属性的增加
print(alex.money)
print(alex.__dict__)
del alex.money # 属性的删除
print(alex.__dict__)
类名() # 会自动调用类中的__init__方法
# Person是一个类 :alex wusir都是这个类的对象
# 类有一个空间,存储的是定义在class中的所有名字
# 每一个对象又拥有自己的空间,通过对象名.__dict__就可以查看这个对象的属性和值
# 实例化所经历的步骤
# 1.类名() 之后的第一个事儿 :开辟一块儿内存空间
# 2.调用 __init__ 把空间的内存地址作为self参数传递到函数内部
# 3.所有的这一个对象需要使用的属性都需要和self关联起来
# 4.执行完init中的逻辑之后,self变量会自动的被返回到调用处(发生实例化的地方)
2.1内存
d = {'k':'v'}
print(d,id(d))
d['k'] = 'vvvv'
print(d,id(d))
# 修改列表\字典中的某个值,或者是对象的某一个属性 都不会影响这个对象\字典\列表所在的内存空间
3. 对象的作用
存储一些值,以后方便自己使用
class File:
def read(self):
with open(self.xxxxx, mode='r', encoding='utf-8') as f:
data = f.read()
return data
def write(self, content):
with open(self.xxxxx, mode='a', encoding='utf-8') as f:
f.write(content)
# # 实例化了一个File类的对象
obj1 = File()
# # 在对象中写了一个xxxxx = 'test.log'
obj1.xxxxx = "test.log"
# # 通过对象调用类中的read方法,read方法中的self就是obj。
# # obj1.read()
obj1.write('alex')
# 实例化了一个File类的对象
obj2 = File()
# 在对象中写了一个xxxxx = 'test.log'
obj2.xxxxx = "info.txt"
# 通过对象调用类中的read方法,read方法中的self就是obj。
# obj2.read()
obj2.write('alex')
总结
"""
如果写代码时,函数比较多比较乱。
1. 可以将函数归类并放到同一个类中。
2. 函数如果有一个反复使用的公共值,则可以放到对象中。
"""
class File:
def __init__(self,path):
self.file_path = path
def read(self):
print(self.file_path)
def write(self,content):
print(self.file_path)
def delete(self):
print(self.file_path)
def update(self):
print(self.file_path)
p1 = File('log.txt')
p1.read()
p2 = File('xxxxxx.txt')
p2.read()
# 1. 循环让用户输入:用户名/密码/邮箱。 输入完成后再进行数据打印。
# ########## 以前的写法
USER_LIST = []
while True:
user = input('请输入用户名:')
pwd = input('请输入密码:')
email = input('请输入邮箱:')
temp = {'username':user,'password':pwd,'email':email}
USER_LIST.append(temp)
for item in USER_LIST:
temp = "我的名字:%s,密码:%s,邮箱%s" %(item['username'],item['password'],item['email'],)
print(temp)
# ########## 面向对象写法
class Person:
def __init__(self,user,pwd,email):
self.username = user
self.password = pwd
self.email = email
USER_LIST = [对象(用户/密码/邮箱),对象(用户/密码/邮箱),对象(用户/密码/邮箱)]
while True:
user = input('请输入用户名:')
pwd = input('请输入密码:')
email = input('请输入邮箱:')
p = Person(user,pwd,email)
USER_LIST.append(p)
for item in USER_LIST:
temp = "我的名字:%s,密码:%s,邮箱%s" %(item.username,item.password,item.email,)
print(temp)
4 命名空间
-
python中一切皆对象,对象的类型就是类。
-
所有的对象都有一个都有一个类型,class A实例化出来的对象的类型就是A类。
-
类型:int、float、str、list、tuple、set、--类(类置的数据类型,内置的类)
-
在类的命名空间:静态变量 绑定方法
-
能定义到类中的
-
静态变量 是个所有对象共享的变量 由对象\类调用,但是不能重新赋值
-
绑定方法 是个自带self参数的函数 由对象调用
-
类方法 是个自带cls参数的函数 由对象\类调用
-
静态方法 是个啥也不带的函数 由对象\类调用
-
property属性 是个伪装成属性的方法 由对象调用 但是不加括号,类名调用就是一个property对象地址
(<property object at 0x0000021011049318>)
-
# 类的成员和命名空间
class A:
Country = '中国' # 静态变量/静态属性 存储在类的命名空间里的
def __init__(self,name,age): # 绑定方法 存储在类的命名空间里
self.name = name # 把变量存储在对象的地址中
self.age = age
def func1(self):
print(self)
def func2(self):pass
def func3(self):pass
def func4(self):pass
def func5(self):pass
a = A('alex',83)
print(a.name)
print(a.Country)
print(A.Country)
a.func1() # == A.func1(a)
# 绑定方法
# 对象.绑定方法() # ==> 类名.绑定方法(对象)
class A:
Country = '中国' # 静态变量/静态属性 存储在类的命名空间里的
def __init__(self,name,age,country): # 绑定方法 存储在类的命名空间里的
self.name = name
self.age = age
def func1(self):
print(self)
def func2(self):pass
def func3(self):pass
def func4(self):pass
def func5(self):pass
a = A('alex',83,'印度')
b = A('wusir',74,'泰国人')
A.Country = '日本人'
print(a.Country)
print(b.Country)
print(A.Country)
# 类中的变量是静态变量
# 对象中的变量只属于对象本身,每个对象有属于自己的空间来存储对象的变量
# 当使用对象名去调用某一个属性的时候会优先在自己的空间中寻找,找不到再去对应的类中寻找
# 如果自己没有就引用类的,如果类也没有就报错
# 对于类来说,类中的变量所有的对象都是可以读取的,并且读取的是同一份变量
# 实现一个类,能够自动统计这个类实例化了多少个对象
# class A:pass
# A.Country = 123 # 属性的增加
# print(A.Country) # 查看或者引用
class A:
count = 0
def __init__(self):
A.count += 1
a1 = A()
print(a1.count)
a2 = A()
print(a1.count)
# 类中的静态变量的用处
# 如果一个变量 是所有的对象共享的值,那么这个变量应该被定义成静态变量
# 所有和静态变量相关的增删改查都应该使用类名来处理
# 而不应该使用对象名直接修改静态变量
# 调用的习惯
# 类名.静态变量
# 对象.静态变量 (对象调用静态变量的时候,不能对变量进行赋值操作 对象.静态变量 = 1UI27)
