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__

 

posted @ 2017-06-23 11:29  真-小亮亮  阅读(244)  评论(0编辑  收藏  举报
#20191216