绑定方法
绑定给对象的方法
特殊之处:函数的第一个形参self就是对象自己。
绑定给对象的方法就会有对象来调用,会把对象自己当成第一个参数传给第一个形参self
类调用,就需要传参数,方法里面有几个参数就要传几个参数
class Student(): school = 'SH' # 类的属性 def __init__(self, name, age, gender): self.name = name # self:对象自己 self.age = age self.gender = gender # 绑定给对象的方法 def tell_info(self): # self:也是对象自己 print("name:%s, age:%s, gender:%s" % (self.name, self.age, self.gender)) stu = Student('kevin', 18, 'male') # 调用类产生一个对象 stu.tell_info() # stu.tell_info(stu) # name:kevin, age:18, gender:male
绑定给类的方法
绑定给类的方法就由类来调用,特殊之处就是:会把类名当成第一个参数传递给方法的第一个形参。
# 绑定给类的方法 # ip:127.0.0.1 port:3306 ====> ip+port可以唯一确定一台计算机上的一款软件 import settings class Mysql(): def __init__(self,ip,port): self.ip = ip self.port = port
@classmethod # 加了classmethod装饰器,该方法就变成了绑定给类的方法 def from_func(cls): # self 就可以写成cls, cls就是类名 print('123') return cls(settings.ip,settings.port) obj = Mysql(settings.ip,settings.port) res = Mysql.from_func()
非绑定方法
非绑定方法就是:不绑定给类使用,也不绑定给对象使用
又叫:静态绑定(关键字:static)
补充:uuid ,只要了解 uuid4,只要随机串的长度一定,理论上,一定会出现重复的可能性。
import uuid print(uuid.uuid4()) # d2cf6751-cc90-4238-90dd-8ebfacd6140c
订单号的不重复:uuid+时间戳。
@staticmethod 装饰器该方法已经谁都不绑定,类和对象都可以直接来调用
class Student(): def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender self.id = self.create_id() """什么时候使用静态方法:一般就是方法里面既不用对象,也不用类的时候就使用静态方法""" @staticmethod # 该方法已经谁都不绑定,谁都能来调用。 def create_id(): import uuid return uuid.uuid4() stu = Student('hua',18,'male') print(stu.id) # 打印随机串 l =str(stu.id)[:13] # 切分随机串 print(l.replace('-','')) # 将-去掉
隐藏属性
在属性名前加__前缀,就会实现一个对外隐藏属性的效果。
class Student(): country = 'China' def __init__(self, name, age): self.__name = name self.__age = age def __func(self): print('from func') obj = Student('hua', 18) print(obj.__dict__) # AttributeError: 'Student' object has no attribute 'name' print(obj.name, obj.age) # hua 18
这种隐藏对外不对内,因为__开头的属性会在类定义时发生统一发生变形:_类名__属性名:
这种变形操作只在类定义的时候发生一次,之后的定义的__开头的属性都不会变形
为什么要隐藏?
因为隐藏属性是对外部对内的,当想在外部使用时,需要在类的内部开放一个接口,返回隐藏属性的值,以便更好的对外做限制。
class Student(): __country = 'China' def __init__(self, name, age): self.name = name self.age = age def __func(self): # _Student__func _类名__函数名 print('from func') def index(self): return self.__country # self._Student__school obj = Student('hua', 18) print(obj.__dict__) # {'_Student__name': 'hua', '_Student__age': 18} print(obj.name, obj.age) # hua 18 obj._Student__func() # from func print(obj.index()) # China
property装饰器
作用:就是把方法伪装成属性来使用
class Student(): __country = 'China' __city = 'shanghai' def __init__(self, name, age, gender): self.__name = name # _Student__name self.age = age self.gender = gender @property def country(self): return self.__country @country.setter def country(self, v): if type(v) is not str: return Student.__country = v @country.deleter def country(self): print("可以删除了") del Student.__country @property def city(self): return self.__city @city.setter def city(self, v): Student.__city = v @city.deleter def city(self): print("可以删除了") del Student.__city stu = Student("kevin", 20, 'female') print(stu.country) stu.country = 'Japan' print(stu.country) del Student.country stu.country('Japan') del stu.country
# 方式2 class Student(): __country = 'China' __city = 'SH' def __init__(self,name,age,gender): self.name =name self.age = age self.gender = gender def get_country(self): return self.__country def set_country(self,v): if type(v) is not str: return Student.__country = v def del_country(self): print('删除') del Student.__country # 这种方法是有顺序要求的 country = property(get_country,set_country,del_country) stu = Student('hua',18,'male') print(stu.country) # China stu.country = 'Japan' print(stu.country) #Japan del stu.country # 删除
课堂练习
class Bmi(): def __init__(self, weight, height): self.weight = weight self.height = height @property def bmi(self): return self.weight / (self.height ** 2) bmi = Bmi(50, 1.55) print(bmi.bmi) # 20.811654526534856
面向对象的三大特征
封装:是一种思想,将冗余的代码,重复的代码都封装成函数,以后每次都调用函数来用
继承:是新建类的一种方式,新建出来的类称为是子类或者叫派生类,被继承的类称为是父类或者叫基类。
多态
子类可以继承基类的所有属性和方法
类解决的问题:对象与对象之间的代码冗余问题
继承解的问题:类与类之间的代码冗余问题
继承方式:
新式类:继承了object类的子子孙孙类都是新式类
经典类:没有继承object类的子子孙孙类都是经典类
# 以学生选课系统为例 class People(): school = 'SH' # 严格依赖继承 def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender class Student(People): def __init__(self, name, age, gender, course): """这个是指名道姓的调用方法,不依赖于继承""" People.__init__(self, name, age, gender) # 有什么特殊之处, self.course = course def choose_course(self): pass stu = Student('kevin', '19', 'male', 'python') # 对象属性的查找顺序:先从对象自己的名称空间查找,如果找不到,再去类中取查找,如果找不到,取继承的父类转中查找, print(stu.school) print(stu.name) class Teacher(People): def __init__(self,name, age, gender, level): People.__init__(self, name, age, gender) # 有什么特殊之处, self.level = level def score(self): pass tea = Teacher("ly", 20, 'female', 10) print(tea.school)