一 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): passclass Bar(Foo): passissubclass(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'}
反射
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 @property10 def price(self):11 # 实际价格 = 原价 * 折扣12 new_price = self.original_price * self.discount13 return new_price14 15 @price.setter16 def price(self, value):17 self.original_price = value18 19 @price.deleter20 def price(self):21 del self.original_price22 23 24 obj = Goods()25 obj.price # 获取商品价格26 obj.price = 200 # 修改商品原价27 print(obj.price)28 del obj.price # 删除商品原价
__module__和__class__
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
#!/usr/bin/env python# -*- coding:utf-8 -*-class C: def __init__(self): self.name = ‘SB'
from lib.aa import Cobj = 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__