十四.Python_面向对象编程

Python面向对象编程精要
本文深入探讨Python面向对象编程的基础与高级特性,包括类的定义、继承、多态、封装、抽象方法、组合对象等核心概念,以及__getattr__、__setattr__、__delattr__、__call__等特殊方法的使用,最后讲解了元类type的基本操作。

Python_面向对象编程

#三大编程范式
# 函数式编程   #代码量少但复杂
# 过程式编程     #将复杂的逻辑分解为一个个小的逻辑功能,从而完成大型复杂的项目的思路
# 面向对象编程    #利用对象的思想进行编程

# 利用函数模拟面向对象
if __name__=="__main__":
    #模拟类
    def dog(name,color,type):
        #模式类的初始化
        def init(name,color,type):
            #利用字典模拟初始化对象
            dog={"name":name,   #使模拟的对象拥有名字的属性
                 "color":color, #使模拟的对象拥有颜色的属性
                 "type":type,   #使模拟的对象拥有类型的属性
                 "bark":bark,  #使模拟的对象拥有bark函数的行为
                 "sleep":sleep,#使模拟的对象拥有sleep函数的行为
            }
            return dog   #返回实例化的对象
        def bark(self):           #bark函数
            print("一条%s的狗:汪汪汪!"%self["color"])  #模拟某个对象的叫的功能
        def sleep(self):
            print("一只%s正在睡觉!"%self["type"])    #模拟某个对象的睡觉的功能
        return init(name,color,type)  #返回实例化的对象

    #利用函数模拟实例化对象的过程
    dog1=dog("小黄","黄色","藏獒")
    #调用模拟的对象叫的功能
    dog1["bark"](dog1)
    #利用模拟对象睡觉的功能
    dog1["sleep"](dog1)

#class
#利用类完成面向对象    class完成面向对象比函数更加专业
#__init__   将类实例化的函数
#self       指的是自己这个类的对象
#
    #对象拥有的两类元素:  1. 对象的数据属性, 2. 对象的函数属性
#用 . 访问对象属性或行为

    class dog:  #创建对象的类
        def __init__(self,name,color,type):  #将类的属性实例化对象
            self.mingzi=name                #给类的属性赋值
            self.yanse=color
            self.leixing=type
        def bark(self):                    #定义类叫的行为
            print("%s 的狗正在汪汪汪!"%self.yanse)
        def sleep(self):                     #定义类睡觉的行为
            print("一只叫 %s 的 %s 正在睡觉!"%(self.mingzi,self.leixing))

    dog2=dog("小黄","黄色","藏獒")   #类实例化为对象
    dog2.bark()                       #对象调用叫的行为
    dog2.sleep()                        #对象调用睡觉的行为

    #  __dict__  获取类或对象的属性字典

    print(dog.__dict__)  #获取类的属性
    print(dog2.__dict__) #获取对象的属性

    #面向对象的增删改查操作

    #查询
    print("这只狗叫 %s"%dog2.mingzi)
    #增
    dog2.leg=5
    print("这只叫%s的狗有%s条腿!"%(dog2.mingzi,dog2.leg))

    #改
    dog2.leg=4
    print("这只叫%s的狗现在还剩%s条腿!" % (dog2.mingzi, dog2.leg))

    #删
    del dog2.leg
    #print(dog2.leg)   AttributeError: 'dog' object has no attribute 'leg'



 

@property

#类存在两种属性:
    # 数据属性
    # 函数属性

# @property  将函数属性的访问方式变为访问数据属性的方式 遵循了统一访问的原则
#   修饰类的函数属性
if __name__=="__main__":
    class dog:
        def __init__(self,name):
            self.name=name
        @property
        def sleep(self):
            return "%s 正在睡觉!"%self.name

    dog1=dog("小黄")
    #访问函数属性
    print(dog1.sleep)
    #访问数据属性
    print(dog1.name)

 

@classmethod类方法

# 类方法
#表示  @classmethod  修饰函数属性,
#作用:使类访问函数属性,传进去的不是self,是一个cls的类

if __name__=="__main__":
    class dog:
        type="藏獒"
        def __init__(self,name):
            self.name=name
        @classmethod   #使函数的访问对象改为类
        def sleep(cls):
            return "一只 %s 正在睡觉!"%cls.type

    print(dog.sleep()) #类访问函数属性

静态方法  @staticmethod

#静态方法  @staticmethod
#作用     把类中的函数定义为静态方法,为一个类定义不同的实例

if __name__=="__main__":
    class dog:
        def __init__(self,name):
            self.name=name
        @staticmethod
        def sleep(name):
            return "%s 正在睡觉!"%name
        @property
        def bark(self):
            return "%s 正在汪汪汪!"%self.name

    print(dog.sleep("小黄"))
    print(dog("小黄1").bark)

 abc 抽象方法

#abc  抽象方法,需要其他类去实现,相当于定义了一个类的模板
#相当于java中的接口,通过实现类(接口)去实现
import abc  #相当于接口模板
if __name__=="__main__":
    class animal(metaclass=abc.ABCMeta):
        @abc.abstractclassmethod
        def sleep(self):
           pass
        @abc.abstractclassmethod
        def bark(self):
           pass

    class dog(animal):
        def __init__(self,name):
            self.name=name
        @property
        def sleep(self):
            return "%s 正在睡觉!"%self.name
        @property
        def bark(self):
            return "%s 正在汪汪汪!" %self.name
    dog1=dog("小黄")
    print(dog1.sleep)
    print(dog1.bark)

 

继承

#面向对象的三种方式
#继承
#多态
#封装

#继承   class(class)
#作用:使字类拥有父类的所有数据属性和函数属性,也可以对父类的数据和函数属性进行修改和添加
# super() 字类调用父类
if __name__=="__main__":
    class animal:
        def __init__(self,name,color):
            self.name=name
            self.type=type
        @property
        def sleep(self):
            print("%s 正在睡觉!"%self.name)
        @property
        def bark(self):
            print("%s 正在叫!"%self.name)

    class dog(animal):
        pass

    dog1=dog("小狗","藏獒")  #默认使用父类animal的数据属性
    dog1.sleep              #默认使用父类animal的函数属性
    dog1.bark             #默认使用父类animal的函数属性

    #super() 字类调用修改父类的方法
    class cat(animal):
        def __init__(self,name,type,color):
            super().__init__(name,type)
            self.color=color
        @property
        def catchLaoShu(self):  #新增方法
            print("%s 捉了只老鼠!")

    cat1=cat("小黄","猫科","黄色")
    cat1.sleep
    cat.catchLaoShu


组合对象

#组合对象
# 指将多个对象组合成一个对象
#组合人类
class head:
    def __init__(self,name,ey):
        self.name=name
        self.eye=eye(ey)
        print("生成 %s" % name)
    @property
    def think(self):
        print("%s 开始思考。。!" %self.name)
class trank:
    def __init__(self,name):
        self.name=name
        print("生成 %s" % name)
    @property
    def stand(self):
        print("%s 站了起来!"%self.name)
class foot:
    def __init__(self,name):
        self.name=name
        print("生成 %s" % name)
    @property
    def walk(self):
        print("%s 走起路来!"%self.name)
class eye:
    def __init__(self,name):
        self.name=name
        print("生成 %s"%name)
    @property
    def see(self):
        print("%s 看东西!"%self.name)
class hand:
    def __init__(self,name):
        self.name=name
        print("生成 %s"%name)
    @property
    def catchthing(self):
        print("%s 拿东西!"%self.name)
class person:
    def __init__(self,name,hea,foo,tran,ey,han):
        self.name=name
        self.head=head(hea,ey)
        self.foot=foot(foo)
        self.tr=trank(tran)
        self.hand=hand(han)
        print("%s组合成功!"%self.name)
    @property
    def think(self):
        self.head.think
    @property
    def catch(self):
        self.hand.catchthing
    @property
    def stand(self):
        self.tr.stand
    @property
    def walk(self):
        self.foot.walk
    @property
    def watch(self):
        self.head.eye.see
if __name__=="__main__":
    person1=person("小明","脑袋","脚","身体","眼睛","手臂")
    person1.think
    person1.stand
    person1.walk
    person1.catch
    person.watch

 mro 类的访问顺序

#mro
#指当前类找不到属性,去找下一个类的顺序
class A:
    def test(self):
        print("A")
class B(A):
    def test(self):
        print("B")
class C(B):
    def test(self):
        print("C")
class D(C):
    def test(self):
        print("D")
class I(A):
    def test(self):
        print("I")
class H(I):
    def test(self):
        print("H")
class G(H):
    def test(self):
        print("G")

class E(D):
    def test(self):
        print("E")
class F(E):
    # def test(self):
    #     print("F")
    pass
if __name__=="__main__":
    f=F()
    f.test()
    print(F.mro())  #类找下一个类的顺序

多态

#多态     继承的子类重写了同一父类的相同方法
#不同子类重写了父类的一个方法
if __name__=="__main__":
    class animal:
        def __init__(self,name):
            self.name=name
        def sleep(self):
            print("动物在睡觉!")

    class cat(animal):
        def __init__(self,name):
            super().__init__(name)
        # def sleep(self):
        #     print("猫在睡觉")


    class dog(animal):
        def __init__(self, name):
            super().__init__(name)

        def sleep(self):
            print("狗在睡觉")

    cat("猫").sleep()
    dog("狗").sleep()

 

封装

#封装
#将类中的属性设置为私有,就叫封装

if __name__=="__main__":
    class animal:
        def __init__(self,name,type):
            self._name=name
            self._type=type
    #如何访问类的私有属性
    print(animal("小黄","dog").__dict__.get("_name")) #获取对象字典get()取值

 

反射

 

#反射
#__getattr()__  当前类获取不到就到父类去找数据或函数
#__setattr()__  设置对象属性
#__delattr()__  删除对象属性
if __name__=="__main__":
    class animal:
        def __init__(self,name):
            self.name=name
    class cat(animal):
        pass


    a=animal("tom")
    c=cat("ca")

    #获取对象属性
    print("animal的name:",a.__getattribute__("name"))
    print("animal的name:",c.__getattribute__("name"))  #__getattr()__  当前类获取不到就到父类去找数据或函数

    #添加数据属性
    a.__setattr__("type","male")
    print(a.__getattribute__("type"))
    #添加函数属性
    def sleep():
        print("睡觉!..")
    a.__setattr__("sleep",sleep)
    a.__getattribute__("sleep")()

    #删除对象属性
    print(a.__dict__)
    a.__delattr__("sleep")
    print(a.__dict__)



 

动态导入模块

# __import()__动态导入模块
time=__import__("time")
#使用模板
print(time.time())

 

内置attr

 

# 内置attr
# getattr()  获取对象属性
#setattr()   #设置对象属性
#delattr()   #删除对象属性
if __name__=="__main__":
    class animal:
        def __init__(self,name):
            self.name=name
    an=animal("小黄")
    #getattr()  类似 __getattr__()
    print(getattr(an,"name"))
    #setattr()  类似  __setattr()__
    setattr(an,"type","male")
    print(getattr(an,"type"))
    #delattr()  类似 __delattr()
    print(an.__dict__)
    delattr(an,"type")
    print(an.__dict__)

__module__,__class__

from item import animal
# __module__  输出类所在的模块
# __class__   输出当前类

a=animal()
print(a.__module__)  #输出模块
print(a.__class__)  #输出类

__isinatance__,__issubclass__

#isinstance()  对象是否是某个类的实例
#issubclass()   某个类是否是另一个类的子类
if __name__=="__main__":
    class animal:
        def __init__(self,name):
            self.name=name

    an=animal("动物")
    # isinatance()对象是否是某个类的实例
    print("an对象是否是animal类的实例:",isinstance(an,animal))

    #issubclass() 某个类是否是另一个类的子类
    class dog(animal):
        pass
    print("dog类是否是animal类的一个子类: ",issubclass(dog,animal))



item

# item   通过添加字典的方式添加属性时会触发item

#getitem()  取值的时候会触发
#setitem()  为对象添加值时会触发
#delitem()  删除对象中的属性时会触发

class animal:
    def __getitem__(self, item):
        print("getitem")
        # self.__dict__.get(item) 从类的字典中取出值
        return self.__dict__.get(item)
    def __setitem__(self, key, value):
        print("setItem")
        #self.__dict__.set(k,v) 为类的字典里添加属性
        self.__dict__.__setitem__(key,value)
    def __delitem__(self, key):
        print("delitem")
        #self.__dict__.pop(k) 从类的字典里删除某个属性
        self.__dict__.pop(key)

if __name__=="__main__":
    an=animal()

    #添加值触发setitem()
    an["name"]="tom"
    print(an.__dict__)  #{'name': 'tom'}
    #取值的时候会触发getitem()
    print(an["name"])  #tom
    #删除值时会触发delitem()
    del an["name"]
    print(an["name"]) # None

with 类  as

#with 类  as

# with as 开始 触发  __enter__函数
# with as  结束 触发 __exit__函数
class Open:
    def __init__(self,name,modu):
        self.name=name
        self.__modu=modu
    def __enter__(self):
        print("enter...")
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("exit...")
        print(exc_type)
        print(exc_val)
        print(exc_tb)

with Open("a.txt","r") as f:
    print(f)

描述符

#描述符  代理其他类的的类叫做描述符
#__set__  创建对象时触发
#__get__  获取描述符的属性时触发
#__del__ #删除描述符属性时触发

#优先关系
    # 类>
    # 数据描述符>  有set方法
    # 对象>
    # 非数据描述符>  没有set方法
    # getattr()方法


class Typehand:
    def __init__(self,name):
        self.name=name
        pass
    def __get__(self, instance, owner):
        print("__get__")
        #被代理类的对象
        print(instance)
        #被代理的类
        print(owner.__dict__)
        #取被代理对象的值
        return instance.__dict__.get("name")
    def __set__(self, instance, value):
        print("__set__")
        #当前类
        print(self)
        #被代理类的对象
        print(instance)
        #被代理类实例化传过来的值
        #print(value)
        #为被代理对象赋值
        instance.__dict__.setdefault("position",value)

        pass
    def __delete__(self, instance):
        print("__delete__")
        #被代理类的对象
        print(instance)
        #删除被代理对象的属性
        instance.__dict__.pop("name")
        pass

class city:
    position=Typehand("x")
    def __init__(self,name,position):
        self.name=name
        self.position=position

#触发描述符set()方法
ci=city("上海","南方")

#触发描述符set()方法
print(ci.position)

#触发描述符del方法
print(ci.__dict__)
del ci.position
print(ci.__dict__)

__del__析构方法

# __del__  对象被销毁时触发该函数

class a:
    def __init__(self):
        pass
    def __del__(self):
        print("__del__")


a1=a()

类的装饰器

#类的装饰器
#定义 @ 与函数装饰器相同

#property
class abc:
    def __init__(self,func):
        self.func=func
    def __get__(self, instance, owner):
        res=self.func(instance)
        setattr(instance,self.func,res)
        return res


class person:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    @property
    def sleep(self):
        print("%s 正在睡觉!"%self.name)

per=person("小明",18)
per.sleep
per.sleep

迭代器协议

#迭代器协议
#满足 __iter__ 和 __next__叫做迭代器

class it:
    #__init__实例化对象
    def __init__(self,num):
        self.num=num
    #通过__iter__方法使对象可迭代
    def __iter__(self):
        return self
    # __next__ 迭代对象
    def __next__(self):
        self.num += 1
        if self.num==60:
            #触发终止
            raise StopIteration
        else:
            return self.num

#实例化对象
i=it(1)
#开始迭代对象
#手动迭代遇到异常会报错
print(next(i))

#for 循环迭代 遇到异常只会终止,不会报错
for a in i:
    print(a)

内置函数

#内置函数
# __slots__  取代__dict__用于存储类的属性
#优点:节省内存
#可以为属性赋值,但不可以添加属性
#可以取值
#
class animal:
   __slots__ = ["name","age"]

an=animal()
#赋值
an.name="tom"
print(an.name)
#删除值
del an.name
#删除属性
an.__slots__.remove("name")
print(an.__slots__) #['age']


#__call__
#调用函数的方式调用对象时会触发
class animal:
    def __call__(self, *args, **kwargs):
        print("call被调用")
        print(*args)
        print(**kwargs)


an=animal()
#调用call函数
an(1,2,3,4,{"x":"1","y":"2"})

#__doc__  注释  获取每个类的注释,每个类的注释不可以被其它类调用
class animal1:
    "这是animal1类的注释"

# __doc__获取类的注释
print(animal1.__doc__)



#__getattribute__  获取类的属性值时会触发,如果出现AttributeError异常,会调用__getattr__函数
#raise Error   自定义异常
class animal2:
    def __init__(self,name):
        self.name=name
    def __getattr__(self, item):
        print("__getattr__")
    def __getattribute__(self, item):
        print("__getattribute__")
        #自定义异常
        raise AttributeError


a2=animal2("猫")
print(a2.name) #__getattribute__  __getattr__   None


#__str__  用于将类输出为字符串
# __repr__ #类中没有定义__str__会调用__repr__函数
# __format__

class animal3:
    def __init__(self,name):
        self.name=name
    def __str__(self):
        return "这是str"
    def __repr__(self):
        return "这是repr"
a3=animal3("x")
#输出对象
print(a3) #这是str


#__format__
tim={"y-m-d":"2016-12-12",
     "m-d-y":"12-12-2016",
     "ymd":"20161212"}
class time1:
    def __init__(self):
        pass
    def __format__(self, format_spec):
        if not format_spec:
            return tim["ymd"]
        return tim[format_spec]

t=time1()
print(format(t,'y-m-d'))





元类

# type  元类  元类可以操纵生成类

#继承元类type,使其拥有元类的特性
class type1(type):
    #__call__创建创造类的对象
    def __call__(self, *args, **kwargs):
        print("__call__")
        print(self, *args, **kwargs)
        obj=object.__new__(self)
        self.__init__(obj,*args,**kwargs)
        return obj

#定义元类为type1
class cat(metaclass=type1):
    def __init__(self,name="小猫"):
        self.name=name
    def sleep(self):
        print("%s 睡觉!"%self.name)

#实例化类触发__new__方法
ca=cat("小狗")
#测试对象的函数
ca.sleep()

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值