面向对象的三大特性
封装
什么是封装?
封装是类的三大特性,封装就是把功能和数据整合在一起?
为什么要有封装?
以为封装能让代码整合度更高
如何使用封装?
直接定义使用即可
私有有属性?
在封装的基础上,我们可以将装到对象或者类中的属性隐藏起来
1:在定义类或者初始化对象时,在属性前加__,就会将该属性隐藏起来,但是该隐藏其实只是一种变形,_类名__属性名,并没有真的隐藏起来
2:该变形操作是在类定义阶段扫描书法时发生的变形,类定义之后添加的__开头的属性不会发生变形
3:该隐藏对内不对外
4:在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有属性
class Student:
__school = '日本校区'
def __init__(self,name,age,gender):
self.__name = name
self.age = age
self.gender = gender
def __choose(self):
print(f"{self.__name}正在选课!")
stu = Student('alen',18,'female')
stu.__name = 111 # 新创建了一个属性
print(stu.__dict__)
print(stu.__name)
print(stu.__dict__)
print(stu._Student__name) # 'alen'
print(stu.__dict__)
print(Student._Student_school)
print(stu._Student__school)
为啥要隐藏属性?
把数据属性隐藏起来的意义是:在类内开放接口,让外界使用接口来操作属性值,我们可以在接口之上附加任意的逻辑,来严格控制外界对属性的操作
把功能属性隐藏起来
class Student:
__school = 'oldbyo' #
def __init__(self,name,age,gender):
self.__name = name
self.__age = age
self.gender = gender
def __choose(self):
print(f"{self.__name}正在选课")
def get_name(self):
print(self.__name) # print(self._Student__name)
def get_age(self):
print(self.__age)
def set_age(self,age):
if type(age) is not int:
print("年龄必须是整型,眼瞎")
return
self.__age = age
def del_age(self):
del self.__age
propetry 把函数伪装成属性
class People:
def __init__(self,name,height,weight):
self.name = name
self.height = height
self.weight = weight
def bmi(self):
return self.weight / (self.height **2)
p = People('egon',1.81,70)
p.height = 1.84
p.bmi()
class People:
def __init__(self,name,height,weight):
self.name = name
self.height = height
self.weight = weight
@property
def bmi(self):
return self.weight / (self.height **2)
p = People('egon',1.81,70)
p.height = 1.84
p.bmi
示列2
class Student:
__school = '东京校区'
def __init__(self,name,age,gender):
self.__name = name
self.age = age
self.gender = gender
def get_name(self):
print("访问接口")
return self.__name
def set_name(self,name):
print('修改操作')
self.__name = name
def del_name(self):
del self.__name
def get_age(self):
retrun self.__age
def set_age(self,age):
if type(age) is not int:
print("年龄必须是整型,傻瓜")
return
def del_age(self):
print("不让删除")
age = property(get_age,set_age,del_age)
name = property(get_name,set_name,del_name)
s1 = Student("alen",18,'female')
s1.age = 19
del s1.age
print(s1.age)
s1.name = 'egon'
del s1.name
示列3
class Student:
__school = '上海校区'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
@property
def name(self):
print("访问")
return self.__name
name.setter
def name(self,name):
self.__name = name
@name.deleter
def name(self):
print("删除")
del self.__name
s1 = Student('alen',18,'female')
s1.name
类中的定义函数
绑定方法:谁来调用就会将谁当作第一个参数传入
绑定给对象的方法:类中定义函数默认就是绑定给对象的方法,应该是由对象来调用,会把对象当作第一个参数传入
绑定给类的方法:在类中的函数加一个装饰器@classmethod,该函数就绑定给类了,应该是由类来调用,会把类当作第一个参数传入
非绑定方法:既不与类绑定也不与对象绑定,就是一个普通函数,谁都可以来调用,没有自动传参的效果,需要在函数添加装饰器staticmethod
class People:
def __init__(self,name,age):
self.name = name
self.age = age
def tell_info(self):
print(f"{self.name}{self.age}")
@classmethod
def foo(cls):
print(cls) # Student
@staticmethod
def bar(x,y,z):
print(x,y,z)
p1 = People('egon',18)
p1.tell_info()
print(People.foo)
People.bar(1,2,3)
示列
settings
IP = '127.0.0.1'
PORT = 3306
import uuid
import Mysql
class MySQL:
def __init__(self,ip,port):
self.mid = self.__create_id()
self.ip = ip
self.port = port
def tell_info(self):
print(f"{self.mid}{self.ip}{self.port}")
@staticmethod
def __create_id():
return uuid.uuid4()
@classmethod
def from_conf(cls):
return cls(settings.IP,settings.PORT)
obj = MySQL('10,1,2,3',3306)
obj.tell_info()
obj2 = MySQL.from_conf()
obj2.tell_info()