不是自己写的:
#子类与父类
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="后羿"
    
View Code

 

posted @ 2020-07-31 21:40    阅读(122)  评论(0编辑  收藏  举报