从他的身上看到了自己从前的影子,原来这样的人是这么的令人生厌,幸好自己从那股烂泥潭中走了出来,万幸呀!以后做事不求能做到多好,只愿不做坏每一件事。也希望自己能早日摆脱从前的自己对自己造成的影响,尽量找到一群上进、有思想、谦逊的人。不多说了,这个问题都存在四天了,还没有思路怎么解决,真是无语,成长路上总有蠢人挡路。
1、封装
什么是封装
封:属性对外是隐藏的,但对内是开放的
装:申请一个名称空间,往里装入一系列名字/属性
为什么要封装
封装数据属性的目的
首先定义属性的目的就是为了给类外部的使用对象使用的
隐藏之后是为了不让外部使用直接使用,需要类内部开辟一个接口
然后让类外部的使用通过接口来间接地操作隐藏的属性
精髓在于:我们可以在接口之上附加任意逻辑,从而严格控制使用者对属性的操作
封装函数属性
首先定义属性的目的就是为了给类外部的使用使用的
隐藏函数属性是为了不让外部使用直接使用,需要类内部开辟一个接口
然后在接口内去调用隐藏的功能
精髓在于:隔离了复杂度
如何封装
如何隐藏:在属性前加上__开头
1、这种隐藏仅仅只是一种语法上的变形操作
2、这种语法上的变形只在类定义阶段发生一次,因为类体代码金金只在类定义阶段检测一次
3、这种隐藏是对外不对内的,即在类的内部可以直接访问,而在类的外部无法直接访问,原因是在类定义
阶段,类体内代码统一发生了一次变形
4、如果不想让子类的方法覆盖父类的,可以将该方法名前加一个开头
class People: __country='China' #_People__country='China' __n=100 #_People__n=100 def __init__(self,name,age,sex): self.__name=name #self._People__name=name self.age=age self.sex=sex def eat(self): print('eat.....') print(People.__country) #People._People__country print(self.__name) #self._People__name People.eat(123) print(People.__country) peo1=People('egon',18,'male') peo1.eat() print(peo1.__name) print(People.__dict__) print(People.__country) print(People._People__country) People.__x=11 print(People.__dict__) peo1=People('egon',18,'male') print(peo1.__dict__) peo1.__x=111 print(peo1.__dict__) class Foo: def __f1(self): #_Foo__f1 print('Foo.f1') def f2(self): print('Foo.f2') self.__f1() #self._Foo__f1 class Bar(Foo): def __f1(self): #_Bar__f1 print('Bar.f1') obj=Bar() obj.f2() class People: def __init__(self,name,age): self.__name=name self.__age=age def tell_info(self): print('%s:%s' %(self.__name,self.__age)) def set_info(self,name,age): if type(name) is not str: # print('用户名必须为str类型') # return raise TypeError('用户名必须为str类型') if type(age) is not int: # print('年龄必须为int类型') # return raise TypeError('年龄必须为int类型') self.__name=name self.__age=age peo1=People('egon',18) peo1.name=123 peo1.age peo1.tell_info() peo1.set_info('egon',19) peo1.tell_info()
2、特性property
property装饰器用于将被装饰的方法伪装成一个数据属性,在使用时可以不用加括号而直接引用
class People: def __init__(self,name,weight,height): self.name=name self.weight=weight self.height=height @property def bmi(self): return self.weight / (self.height ** 2) peo1=People('egon',75,1.8) peo1.height=1.85 print(peo1.bmi) class People: def __init__(self,name): self.__name=name @property # 查看obj.name def name(self): return '<名字是:%s>' %self.__name @name.setter #修改obj.name=值 def name(self,name): if type(name) is not str: raise TypeError('名字必须是str类型傻叉') self.__name=name @name.deleter #删除del obj.name def name(self): # raise PermissionError('不让删') print('不让删除傻叉') # del self.__name peo1=People('egon') # print(peo1.name) # print(peo1.name) # peo1.name='EGON' # print(peo1.name) del peo1.name class People: def __init__(self,name): self.__name=name def tell_name(self): return '<名字是:%s>' %self.__name def set_name(self,name): if type(name) is not str: raise TypeError('名字必须是str类型傻叉') self.__name=name def del_name(self): print('不让删除傻叉') name=property(tell_name,set_name,del_name) peo1=People('egon') print(peo1.name) peo1.name='EGON' print(peo1.name) del peo1.name
3、绑定方法与非绑定方法
1、绑定方法
特性:绑定给谁就应该由谁来调用,谁来调用就会将谁当作第一个参数自动传入
精髓在于自动传值
绑定方法分为两类
1、绑定给对象方法
在类内部定义的函数(没有被任何装饰器修饰的),默认就是绑定给对象用的
2、绑定给类的方法
在类内部定义的函数如果被装饰器@classmethod装饰
那么则是绑定给类的,应该由类来调用,类来调用就自动将类当作第一个参数自动传入
2、非绑定方法
类中定义的函数如果被装饰器@staticmethod装饰,那么该函数就变成非绑定方法
即不与类绑定,又不与对象绑定,意味着类与对象都可以来调用
但是无论谁来调用,都没有任何自动传值的效果,就是一个普通函数
3、应用
如果函数体代码需要用外部传入的类,则应该将该函数定义成绑定给类的方法
如果函数体代码需要用外部传入的类,则应该将该函数定义成绑定给对象的方法
如果函数体代码既不需要外部传入的类也不需要外部传入的对象,则应该将该函数定义成非绑定方法/普通函数
class Foo: @classmethod def f1(cls): print(cls) def f2(self): print(self) obj=Foo() print(obj.f2) print(Foo.f1) Foo.f1() print(Foo) 1、f1绑定给类的 了解:绑定给类的应该由类来调用,但对象其实也可以使用,只不过自动传入的仍然是类 print(Foo.f1) print(obj.f1) Foo.f1() obj.f1() 2、f2是绑定给对象的 obj.f2() Foo.f2(obj) import settings import uuid class Mysql: def __init__(self,ip,port): self.uid=self.create_uid() self.ip=ip self.port=port def tell_info(self): print('%s:%s' %(self.ip,self.port)) @classmethod def from_conf(cls): return cls(settings.IP, settings.PORT) @staticmethod def func(x,y): print('不与任何人绑定') @staticmethod def create_uid(): return uuid.uuid1() 默认的实例化方式:类名(..) obj=Mysql('10.10.0.9',3307) 一种新的实例化方式:从配置文件中读取配置完成实例化 obj1=Mysql.from_conf() obj1.tell_info() obj.func(1,2) Mysql.func(3,4) print(obj.func) print(Mysql.func) print(obj.uid)