• Python-面向对象进阶


    一 isinstance(obj,cls)和issubclass(sub,super)

    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)

    __setitem__,__getitem,__delitem__

    在Python中,如果我们想实现创建类似于序列和映射的类,可以通过重写魔法方法__getitem__、__setitem__、__delitem__方法去模拟。

    __getitem__(self,key):返回键对应的值。

    __setitem__(self,key,value):设置给定键的值

    __delitem__(self,key):删除给定键对应的元素。

    class Foo:
        def __init__(self,name):
            self.name=name
        def __getitem__(self, item):
            # print("getitem")
            return self.__dict__[item]
        def __setitem__(self, key, value):
            # print("setitem",key,value)
            self.__dict__[key]=value
        def __delitem__(self, key):
            # print('del obj[key]时,我执行')
            self.__dict__.pop(key)
    #如果没有item方法,需要判断obj的类型,函数将多出于功能无关的逻辑
    # def func(obj,key,value):
    #     if isinstance(obj,dict):
    #         obj[key]=value #obj['name']='123123'
    #     else:
    #         setattr(obj,key,value)
    
    #加上item方法,则无需判断obj的类型,不管是dict类型还是Foo类型,都以统一的一种[]的方式操作
    def func(obj,key,value):
        obj[key]=value #obj['name']='123123'
    dic={'name':'egon','age':18}
    print(dic)
    obj=Foo('egon')
    func(dic,'name','egon666')
    print(dic)
    print(obj.__dict__)
    func(obj,'name','123123123123')
    print(obj.__dict__)
    
    #输出结果
    {'name': 'egon', 'age': 18}
    # {'name': 'egon666', 'age': 18}
    # {'name': 'egon'}
    # {'name': '123123123123'}
    __setitem__,__getitem,__delitem__

    反射

    1 什么是反射

    反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

    2 python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

    说反射之前先介绍一下__import__方法,这个和import导入模块的另一种方式

     import  commons
    __import__('commons') 

    如果是多层导入:

    from list.text import commons 
    __import__(' list.text.commons',fromlist=True) #如果不加上fromlist=True,只会导入list目录

    反射即想到4个内置函数分别为:getattr、hasattr、setattr、delattr  获取成员、检查成员、设置成员、删除成员下面逐一介绍先看例子:

    class BlackMedium:
        feature='Ugly'
        def __init__(self,name,addr):
            self.name=name
            self.addr=addr
    
        def sell_house(self):
            print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name)
        def rent_house(self):
            print('%s 黑中介租房子啦,傻逼才租呢' %self.name)
    
    b1=BlackMedium('万成置地','回龙观天露园')
    
    #检测是否含有某属性
    print(hasattr(b1,'name'))
    print(hasattr(b1,'sell_house'))
    
    #获取属性
    n=getattr(b1,'name')
    print(n)
    func=getattr(b1,'rent_house')
    func()
    
    # getattr(b1,'aaaaaaaa') #报错
    print(getattr(b1,'aaaaaaaa','不存在啊'))
    
    #设置属性
    setattr(b1,'sb',True)
    setattr(b1,'show_name',lambda self:self.name+'sb')
    print(b1.__dict__)
    print(b1.show_name(b1))
    
    #删除属性
    delattr(b1,'addr')
    delattr(b1,'show_name')
    delattr(b1,'show_name111')#不存在,则报错
    
    print(b1.__dict__)

    property

    一个静态属性property本质就是实现了get,set,delete三种方法

     1 class Goods:
     2 
     3     def __init__(self):
     4         # 原价
     5         self.original_price = 100
     6         # 折扣
     7         self.discount = 0.8
     8 
     9     @property
    10     def price(self):
    11         # 实际价格 = 原价 * 折扣
    12         new_price = self.original_price * self.discount
    13         return new_price
    14 
    15     @price.setter
    16     def price(self, value):
    17         self.original_price = value
    18 
    19     @price.deleter
    20     def price(self):
    21         del self.original_price
    22 
    23 
    24 obj = Goods()
    25 obj.price         # 获取商品价格
    26 obj.price = 200   # 修改商品原价
    27 print(obj.price)
    28 del obj.price     # 删除商品原价
    property应用

     __module__和__class__

     __module__ 表示当前操作的对象在那个模块

     __class__     表示当前操作的对象的类是什么

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    class C:
    
        def __init__(self):
            self.name = ‘SB'
    from lib.aa import C
    
    obj = C()
    print obj.__module__  # 输出 lib.aa,即:输出模块
    print obj.__class__      # 输出 lib.aa.C,即:输出类

    __call__

    对象后面加括号,触发执行。

    注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

    class Foo:
    
        def __init__(self):
            pass
        
        def __call__(self, *args, **kwargs):
    
            print('__call__')
    
    
    obj = Foo() # 执行 __init__
    obj()       # 执行 __call__
  • 相关阅读:
    SEUOJ上几道水题
    项目计划
    软件工程03
    件工程个人作业02
    软件工程个人作业01
    学习进度条
    软件工程第一次博客
    异常分析
    多态
    Java覆盖
  • 原文地址:https://www.cnblogs.com/zjltt/p/7047961.html
Copyright © 2020-2023  润新知