day 26 绑定方法,非绑定方法,面向对象串讲

绑定方法:
绑定方法 对象绑定方法/类的绑定方法
绑定方法:特殊之处,绑定给谁就是谁来掉,并且会把自身传过来

类的绑定方法:绑定给类的,类来调用,会把类自身传过来

类的绑定方法用在什么地方?
不需要通过对象,只需要通过类就能调取,用类的绑定方法
类的绑定方法,可以由对象来调
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)
@classmethod
def get_obj_by_name(cls,name):
#1 去文件中查找名字为 name 的pickle文件
#2 反序列化成对象
#3 return 对象
pass
def get_obj_by_name(self,name):
# 1 去文件中查找名字为 name 的pickle文件
# 2 反序列化成对象
# 3 return 对象
pass


#
# per1=Person.test()
#
# per2=Person('nick',18)


# admin=Person.get_obj_by_name('lqz')
# admin.create()
'''
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
# lqz=Admin.get_obj_by_name('lqz')


admin=Admin.get_obj_by_name1(None,'lqz')

def get_obj_by_name2(type_class,name):
# 1 去文件中查找名字为 name 的pickle文件
# 2 反序列化成对象
# 3 return 对象
pass


# admin=Admin('',19)
# admin1=admin.get_obj_by_name1('lqz')


'''

#类的绑定方法,可以由对象来调
class Person:
'''
注释的内容

'''
def __init__(self,name,age):
# print(self)
self.name=name
self.age=age
@classmethod
def test(cls):
print(cls)
print('类的绑定方法')

# Person.test()
p=Person('nick',18)
#对象可以调用类的绑定方法,也是把该对象的类传入
p.test()


#总结:
-classmethod 是个装饰器,放在类中函数的上面,该函数就变成了类的绑定方法
-类的绑定方法由类来调用,自动把类传过去(对象也可以调,一般不用)
-类的绑定方法用在什么地方?
-不需要通过对象,只需要通过类就能完成某些事的时候,就把该方法定义为类的绑定方法




非绑定方法
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',19)
# print(p.id)
# print(p.get_uuid())
print(Person.get_uuid())
#面向对象高级:Person类也是一个特殊的对象


串讲
面向对象最本质解决的是:提供可扩展性

类与对象
程序中必须先有类,再有对象
类中有属性,有方法
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__.lower()
#文件路径
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'

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)




继承查找顺序(新式类,经典类)
广度优先和深度优先
在子类中调用父类的方法:
1.指名道姓
2.super(类名,对象).父类的方法名() super 严格按照mro列表查找
派生
多态和多态性
控制子类必须实现父类的方法:abc模块,通过抛异常
鸭子类型:不用父类强制约束,人为约束

封装
组合也属于封装
隐藏属性和方法
用__放在属性或者方法前面:能把属性和方法隐藏
隐藏属性为了安全
隐藏方法为了隔离复杂度
propetory:把方法包装成数据属性
修改,删除
@方法名.setter
@方法名.deleter

classmethod:类的绑定方法
staticmethod:静态方法(非绑定方法)



原文地址:https://www.cnblogs.com/wwei4332/p/11429602.html