#子类与父类 class People: def __init__(self,name="爸爸"): self.age = 99 self.name = name self.sex = "男" print("父类初始化") def out(self): print("父类下的name:%s"%(self.name)) def outage(self): print(self.age) class Student(People): def __init__(self,name,age): super().__init__(name) self.name = name self.age = age print("子类初始化") def out(self): print("子类下的name:%s"%(self.name)) super().out() People(self.name).out() super().outage() print(super().outage()) # 这一行报错,我想在子类方法内输出父类属性 print(People().name) s = Student("wusen",18) s.out() """ 子类初始化父类:super().__init__(参数) 子类内部不可以调用父类属性 子类内部可以调用父类方法 super().fun1() """ """ 组合:把一个类的 对象当成另外一个类的属性""" """ Java里面的接口跟 python继承差不多""" #https://pypi.org/project/zope.interface/ #抽象类只能被继承不可以被 实例化 import abc class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def eat(self): pass @abc.abstractmethod def sleep(self): pass class Pig(Animal): def __init__(self): super().__init__() def eat(self): print("猪在吃 饭") def sleep(self): print("猪在睡觉") pig1=Pig() pig1.eat() """ 第二特性 多态 """ #一个类有多个形态 就叫多态 #就跟上面那个抽象类接口里面的方法一样 就是多态性 #记住形参与实参 能把变量归一化 def function(animal): animal.sleep() """鸭子类型:就是不继承,跟上面效果一样""" class Text: def read(self): pass def write(self): pass class Disk: def read(self): pass def write(self): pass """ 第三大特性 封装 """ #属性隐藏 class A: __name="wusen" age=100 a=A() a.age A.__dict__ #在类内部可以直接使用 #他会把__name 变成 _类__name #子类无法覆盖父类__开头的属性 a._A__name #类之后定义就不会变形 a.__y="sadas" print(a.__y) """ 这样玩还可以 """ class A: def __fun1(self): print("A.fun1") def fun2(self): print("A.fun2") self.__fun1() class B(A): def fun1(self): print("B.fun1") b=B() b.fun2() """ 隐藏是为了分离内外, 不让他直接访问修改 比如:取款函数 将插卡细节隐藏 """ """ 装饰器property""" #把函数当成属性 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("wusen",1.70,70) p.bmi #不可以给p.bmi=22 不可以这样写 class People: def __init__(self,name,age): self.__name=name self.__age=age self.name @property def name(self): print("#"*100) return self.__name @name.setter def name(self,value): self.__name=value @name.deleter def name(self): print("不可以删除") p=People("w",11) p.name="wusen" del p.name p.name """绑定与非绑定""" #绑定 #非绑定 class Foo: def __init__(self): self.name="wusen" print("初始化") def fun1(self): print("fun1") print(self.name) @classmethod def fun2(a):#形参写啥都可以,一般他写cls print(a) print("fun2") @staticmethod#这就是非绑定方法 def fun3(): print("fun3") f=Foo() f.fun1 f.fun2 f.fun1() f.fun2() print(Foo.fun1) print(Foo.fun2) print(Foo.fun2()) print(Foo.fun1(f)) Foo.fun3 f.fun3 f.fun3(f) """ def 绑定对象: 绑定方法 classmethod 绑定类 非绑定 statucmethod 类和对象都可以调用 ==》就是把类外的函数封装到类内 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++ """ import hashlib import time h=hashlib.md5(str(time.time()).encode("utf-8")) h.hexdigest() """ 反射 需求:用户输入 s="name" 调用 obj.name 而不是obj."name" """ class People: def __init__(self): self.name="wusen" self.age=24 def tell(self): print("dsada") p=People() hasattr(p,"tell") #判断p下有没有这个属性 getattr(p,"nameq","不存在")#不存在就报错了 fun=getattr(p,"tell","不存在") fun() setattr(p,"namae","asdasd")#不存在也没啥事创建新属性 delattr(p,"namaae")#不存在会报错 内置对象 一、isinstance(obj, cls) 检查obj是否是类 cls 的对象 class Foo(object): pass obj = Foo() isinstance(obj, Foo) 二、issubclass(sub,super) 检查sub类是否是 super 类的派生类 class Foo(object): pass class Bar(Foo): pass issubclass(Bar, Foo) "item系列 去操作属性 变成字典" class Foo: def __init__(self): self.name="wusen" def __getitem__(self,item): print("getitem",item) return self.__dict__[item] def __setitem__(self,key,value): print(key,value) def __delitem__(self,key): print(key) obj=Foo() obj.__dict__ obj.name obj["namea"] #将类变成字典 class People: def __init__(self): self.name="wusen" self.age=24 def __str__(self): print("*") return "结束" def __del__(self): print("已删除") p=People() print(p) del p exec("""print("Nishigouu")""")
View Code
自己总结的:
''' python类中的三大特性:封装、继承、多态 封装:根据职责将属性和方法封装到一个抽象的类中。 继承:实现代码的重用,不需要重复编写代码。子类拥有父类所有的属性和方法。也可以重新父类方法。 多态:不同的对象调用相同的代码,产生不同的效果,提高代码的灵活性。 ''' # -------------继承----------- # class Father(): # name = '父亲' # class Son(Father): # def __init__(self): # super().__init__() # print(super().name) #常用: 调用父类方法以及属性 # print(Father.name) #不用这个 # s = Son() # print(s.name) # --------------封装---------------- # 把属性和方法封装隐藏起来 君子协议 # class A(): # __name = 'wusen' # a = A() # print(a._A__name) # --------------多态-------- # class A(): # def sleep(self): # print('A') # class B(): # def sleep(self): # print('B') # def fun(obj): # obj.sleep() # a = A() # fun(a) # -------抽象类--------- # 只可以被继承,不可以被实例化 # 把大部分类似的属性和方法提取出来 # 介于接口与类之间的东西,和多态还是有一定的区别的 # import abc # class Animal(): # @abc.abstractmethod # def sleep(self): # pass # class Pig(Animal): # def sleep(self): # print('猪') # p = Pig() # p.sleep() # --------装饰器------ # property就是将方法变成属性 # class A(): # name = 'wusen' # @property # def detail(self): # return f'seeing {self.name} is a visual feast' # a = A() # print(a.detail) # ------绑定方法与非绑定方法--------- ''' 普通的:正常写代码,传参self 绑定方法:传参cls 非绑定方法:不需要传参 ''' # class A(): # def fun1(self): # print('fun1') # @classmethod # def fun2(cls): # # print(cls.fun1(cls)) # print('fun2') # @staticmethod # def fun3(): # print('fun3') # a = A() # A.fun1(A)#普通的类直接调用 # a.fun1()#普通的对象调用 # A.fun2()#绑定方法 类调用 # a.fun2()#绑定方法 对象调用 # A.fun3()#非绑定方法,类调用 # a.fun3()#非绑定方法 对象调用 # -----检测是否是派生类,或者是不是这个类--- # isinstance(obj,cls)和issubclass(sub,super) # --------反射==映射-------我就不写代码了,写了好几遍了 # ------元类-------- # 元类:生成类的类 # 元类是父类的祖宗 # print(type(str)) # -------单例模式----- # 就是写代码,属性如果存在证明对象已经创建,那么就不生成新东西了,否则生成对象
View Code
元类:(不想自己写了,累)
# -*- coding: utf-8 -*- """ Created on Mon Jul 13 14:20:26 2020 @author: Administrator """ 储备知识exec 参数一 字符串命令 参数二 全局作用域 默认globals 参数三 局部作用域 默认locals exec("""""",g字典,l字典) 创建的变量会到局域作用域 一切皆对象 到底怎么用 1都可以被引用 2都快可以当作函数的参数被传入 3都可以当作函数的返回值 4都可以当作容器类型 print(type(str)) 产生类的类称之为元类 所以默认定义为class的类,产生他们的就叫做元类 ?那么父类是不是元类呢 type("People",object,) 类的三要素:类名 基类 类的名称空间 class_name="People" class_base=(object,) l={} class_body=""" def __init__(self): self.name="wusen" self.age=24""" exec(class_body,globals(),l) l p=type(class_name,class_base,l) print(p()) p().name # if "Wusen".istitle(): raise TypeError("sadas") print("结束") #自定义元类 class MyMeta(type): def __init__(self,class_name,class_base,l): print("元类初始化") if not class_name.istitle(): raise TypeError("类名首字母必须是大写") if "__doc__" in l.keys(): # print(l) # print("注释为:",l["__doc__"].strip(),"a") if l["__doc__"].strip() == "": raise TypeError("你的注释为空") else: raise TypeError("你有注释嘛...") super().__init__(class_name,class_base,l) def __call__(self,*args,**kwargs): print(args) print("触发CALL") obj=object.__new__(self) self.__init__(obj,*args,**kwargs) return obj """ 1.先创造空对象 2.初始化 3.返回 """ class People(metaclass=MyMeta): """ 这是一个人的函数 """ def __init__(self,name,age): print("初始化 People") self.name=name self.age=age def __call__(self): print("调用") #知识储备 #__call__方法 #People.__call__ p=People("wusen",22) p.name p2=p() """应用--》单例模式 参数都一样的东西 比如mysql参数都一样""" #实现方式一 class MySql: __instance=None def __init__(self): self.host="192.168.1.1" self.port=3306 @classmethod def singleton(cls): if cls.__instance is None: print("第一次创建") print(cls.__instance) obj=cls() cls.__instance=obj print(cls().__instance) print(obj.__instance) print(obj.port) return obj else: print("对象已经存在") return cls.__instance m1=MySql.singleton() m2=MySql.singleton() #实现方式二 class MyMeta(type): __instance=None # def __call__(self,*args,**kwargs): # print("CALL") # if self.__instance == None: # obj=self # self.__instance=obj # return self.__instance def __call__(self,*args,**kwargs): print("CALL") if self.__instance == None: obj=object.__new__(self) self.__init__(self) self.__instance=obj return self.__instance class Mysql(metaclass=MyMeta): def __init__(self): self.host="192.168.1.1" self.port=3306 m1=Mysql() m2=Mysql() m1 is m2 练习题1 将数据属性变成大写 class Mymeta(type): def __init__(self,class_name,class_base,l): super().__init__(class_name,class_base,l) print("元类初始化") print(l) del l["name"] print(l) class People(metaclass=Mymeta): name="sad" def __init__(self): self.name="后羿"