1. 绑定方法和非绑定方法
绑定方法 对象绑定方法/类的绑定方法
绑定方法:特殊之处,绑定给谁就是谁来调,并且会把自身传过来
类的绑定方法:绑定给类的,类来调用,会把类自身传过来
类的绑定方法用在什么地方:不需要通过对象,只需要通过类就能获取到一些东西的时候
类的绑定方法可以用对象来调
class Person:
def __init__(self,name,age):
print(self)
self.name = name
self.age = age
@classmethod
def test(cls):
print(cls)
print('类的绑定方法')
# 类实例化产生对象,返回
return cls('lqz',19)
Person.test()
Person('nick',18)
class Admin:
def __init__(self,name,age):
print(self)
self.name = name
self.age = age
@classmethod
# 类的绑定方法
def get_obj_by_name(cls,name):
# 取到类的名字
type_class = cls.__name__.lower()
# 1 去文件中查找名字为name的pickle文件
# 2 序列化成对象
# 3 return 对象
pass
# 对象的绑定方法
def get_obj_by_name1(self,name):
# 1 去文件中查找名字为name的pickle文件
# 2 序列化成对象
# 3 return 对象
pass
# 类
admin = Admin.get_obj_by_name('lqz')
admin = Admin.get_obj_by_name1(None,'lqz')
# 对象
admin = Admin('nick',19)
admin1 = admin.get_obj_by_name('lqz')
# 类的绑定方法可以用对象来调
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
@classmethod
def test(cls):
print(cls)
print('类的绑定方法')
# Person.test()
p = Person('nick',18)
# 对象可以调用类的绑定方法,也是把该对象的类传入
p.test()
'''
总结:
classmethod 是个装饰器,放在类中的函数上面,该函数就变成了类的绑定方法
类的绑定方法由类来调用,自动把类传过去(对象也可以调,一般不用)
类的绑定方法用在什么地方?
不需要通过对象,只需要通过类就能完成某些事的时候,就把该方法定义为类的绑定方法
'''
2. staticmethod 非绑定方法
staticmethod 非绑定方法,定义在类内部,普通方法,谁都不绑定
对象/类都可以调用,但是不会自动传值
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def object_method(self):
print('我是对象绑定方法,对象来调用我')
@classmethod
def class_method(cls):
print('我是类的绑定方法,类来调用我')
# 当成一个普通函数,只不过是写在类内部的
@staticmethod
def static_method():
print('我是静态方法,谁都不绑定')
# 静态方法(非绑定方法)
# 类来调用
Person.static_method()
# 对象来调用
p = Person('nick',19)
p.static_method()
'''
# 生成一个唯一的id号
import uuid
print(uuid.uuid4())
'''
# 静态方法(非绑定方法)的作用
# 跟类和对象都没有关系的时候,可以定义成静态方法,一般在类内部使用,类外部也可以使用
# 就是一个普通函数,想把它拿到类中管理,就可以定义成静态方法
class Person:
def __init__(self,name,age):
self.id = self.get_uuid()
self.name = name
self.age = age
# 当成一个普通函数,只不过是写在类内部的
@staticmethod
def static_method():
print('我是静态方法,谁都不绑定')
@staticmethod
def get_uuid():
import uuid
return uuid.uuid4()
import uuid
def get_uuid():
return uuid.uuid4()
a = uuid.uuid4()
# p = Person(uuid.uuid4(),'nick',18)
# p = Person(get_uuid(),'nick',18)
p = Person('nick',18)
print(p.id)
print(Person.get_uuid())
# 面向对象高级:Person类也是一个特殊的对象
3. 面向对象串讲
# 面向对象最本质解决的是:提供可扩展性
# 类与对象
# 程序中必须先有类,再有对象
# 类中有属性,有方法
class Person:
# 类属性
school = 'oldboy'
count = 0
# 对象的绑定方法,初始化方法完成对象的初始化
# 特殊之处,类实例化的时候自动调用
def __init__(self,name='lqz'):
Person.count += 1
self.name = name
self.age = 19
p = Person('nick')
# 对象是不能修改类属性的
# 类属性只能类来修改
print(Person.__dict__)
p.school = 'ppp'
print(p.__dict__)
# 绑定方法
# 定义在类内部,没有装饰器装饰的方法都是对象的绑定方法
# 需要对象来调用,对象调用的时候,会把自身传入
class Person:
def __init__(self,name='lqz'):
self.name = name
self.age = 19
def change_name(self,name):
self.name = name
p = Person()
p.change_name('xxx')
# 本质就是 Person.change_name(p,'xxx')
# 对象交互
class Person:
def __init__(self,name='lqz'):
self.name = name
self.age = 19
def change_name(self,name):
self.name = name.upper()
# 继承
# 减少代码冗余
# 选课系统,每个类应该有两个方法
# 方法一:根据名字获取对象
# 方法二:保存对象自身的功能
import pickle
import os
class BaseClass:
@classmethod
def get_obj_by_name(cls,name):
# 字符串
# admin
class_name = cls.__name__.upper()
# 文件路径
path = os.path.join(class_name,name)
with open(path,'rb') as f:
obj = pickle.load(f)
return obj
def save(self):
# 对象拿到类self.__class__
cls = self.__class__
class_name = cls.__name__.lower()
#
path = os.path.join(class_name,self.name)
with open(path,'wb') as f:
pickle.dump(self,f)
return True
class Admin(BaseClass):
def register(self,name,password):
self.name = name
self.password = password
self.save()
class Student(BaseClass):
def __init__(self):
self.name = ''
self.password = ''
self.school = ''
self.course_list = []
def choose_course(self,course_name):
self.course_list.append(course_name)
self.save()
# 调用接口层的注册方法
def register_interface(name,pwd):
obj = Admin.get_obj_by_name(name)
if not obj:
admin = Admin()
admin.register(name,pwd)
#### 写在用户层
name = input('name')
password = input('password')
register_interface(name,password)
#### 接口层
def choose_course_interface(student_name,course_name):
# 取到学生对象
student = Student.get_obj_by_name(student_name)
student.choose_course(course_name)
# 学生选课功能
# 用户功能层
# 假设课程全部打印出来了
course_name = 'linux'
student_name = 'bob'
choose_course_interface(student_name,course_name)
def check_all_student_course(student_name):
student = Student.get_obj_by_name(student_name)
return student.get_courses()
# 查询学生选的所有课程
check_all_student_course(student_name)
# 继承查找顺序(新式类,经典类)
# 广度优先和深度优先
# 在子类中调用父类的方法
# 指名道姓
# super(类名,对象).父类的方法名() super 严格按照mro列表查找
# 派生
# 多态和多态性
# 控制子类必须实现父类的方法:abc模块,通过抛异常
# 鸭子类型:不用父类强制约束,人为约束
# 封装
# 组合也属于封装
# 隐藏属性和方法
# 用__放在属性或者方法面前:能把属性和方法隐藏
# 隐藏属性为了安全
# 隐藏方法为了隔离复杂度
# propertory:把方法包装成数据属性
# 修改:@方法名.setter+6
# 删除:@方法名.deleter
# classmethod:类的绑定方法
# staticmethod:静态方法(非绑定方法)