一、isinstance和issubclass
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)

  

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

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

下列方法适用于类和对象(一切皆对象,类本身也是一个对象)
hasattr(obj,xxx)方法:检测obj是否含有(xxx)属性 返回bool值
ret=getattr(obj,xxx)方法:获取xxx属性,没有则返回None(也可以设置默认值)

class Foo:
f = '类的静态变量'
def __init__(self,name,age):
self.name=name
self.age=age def say_hi(self):
print('hi,%s'%self.name) obj=Foo('egon',73) #检测是否含有某属性
print(hasattr(obj,'name'))
print(hasattr(obj,'say_hi')) #获取属性
n=getattr(obj,'name')
print(n)
func=getattr(obj,'say_hi')
func()
print(getattr(obj,'aaaaaaaa','不存在啊')) #报错

setattr(obj,key,value)方法:给对象增加新属性或者修改原有的属性
delattr(obj,xxx)方法:删除属性

class Foo:
f = '类的静态变量'
def __init__(self,name,age):
self.name=name
self.age=age def say_hi(self):
print('hi,%s'%self.name) obj=Foo('egon',73) # #设置属性
setattr(obj,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
setattr(obj,'name','haha')
print(obj.__dict__)
print(obj.show_name(obj))
print(obj.name) # #删除属性
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111')#不存在,则报错
print(obj.__dict__)

3反射的应用

类也是对象

class Foo(object):

    staticField = "old boy"

    def __init__(self):
self.name = 'wupeiqi' def func(self):
return 'func' @staticmethod
def bar():
return 'bar' print getattr(Foo, 'staticField')
print getattr(Foo, 'func')
print getattr(Foo, 'bar')

反射当前模块成员

#!/usr/bin/env python
# -*- coding:utf-8 -*- import sys def s1():
print 's1' def s2():
print 's2' this_module = sys.modules[__name__] hasattr(this_module, 's1')
getattr(this_module, 's2')

导入其他模块,利用反射查找该模块是否存在某个方法

#!/usr/bin/env python
# -*- coding:utf-8 -*- def test():
print('from the test') 复制代码
#!/usr/bin/env python
# -*- coding:utf-8 -*- """
程序目录:
module_test.py
index.py 当前文件:
index.py
""" import module_test as obj #obj.test() print(hasattr(obj,'test')) getattr(obj,'test')()

  

 三、魔法方法

1、__str__和__repr__
改变对象的字符串显示__str__,__repr__
自定制格式化字符串__format__

#_*_coding:utf-8_*_

format_dict={
'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
}
class School:
def __init__(self,name,addr,type):
self.name=name
self.addr=addr
self.type=type def __repr__(self):
return 'School(%s,%s)' %(self.name,self.addr)
def __str__(self):
return '(%s,%s)' %(self.name,self.addr) def __format__(self, format_spec):
# if format_spec
if not format_spec or format_spec not in format_dict:
format_spec='nat'
fmt=format_dict[format_spec]
return fmt.format(obj=self) s1=School('oldboy1','北京','私立')
print('from repr: ',repr(s1))
print('from str: ',str(s1))
print(s1) '''
str函数或者print函数--->obj.__str__()
repr或者交互式解释器--->obj.__repr__()
如果__str__没有被定义,那么就会使用__repr__来代替输出
注意:这俩方法的返回值必须是字符串,否则抛出异常
'''
print(format(s1,'nat'))
print(format(s1,'tna'))
print(format(s1,'tan'))
print(format(s1,'asfdasdffd'))
class B:

     def __str__(self):
return 'str : class B' def __repr__(self):
return 'repr : class B' b=B()
print('%s'%b)
print('%r'%b)

%s和%r

2、 __new__、__init__、__del__

class Animal(object):

     def __new__(cls, *args, **kwargs):#覆盖了基类object的__new__方法
print("this is 构造方法")
addr=super().__new__(cls) #必须调用父类开辟空间的方法(操作底层硬件) 默认传参 cls(当前类名)
print("addr",addr)
return addr
def __init__(self,name,age):#覆盖了基类object的__init__方法
print("self",self)
print("this is 初始化方法")
self.name=name
self.age=age
def __del__(self): #覆盖了基类object的__del__方法
print("i am 析构方法!") alex=Animal("alex",34)
'''
alex=Animal("alex",34)
类实例化过程:
1 __new__方法获得空间地址(实例对象创建第一步必须创建空间)
2 将空间地址作为第一个位置参数传给__init__ ,完成实例空间赋值属性的过程 self变量等于addr变量 存储地址空间指针
3 空间地址失去了实例对象的指向(或者程序结束) 会调用__del__
'''
class Config(object):
_instance=None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance=super().__new__(cls)
return cls._instance
file_path=""
data="mysql"
app=["app01","app02"] cf=Config()
cf2=Config() print(id(cf))
print(id(cf2))
print(cf == cf2)

单例模型

# python 垃圾回收机制: 任何对象在执行过程中失去了指引,则被回收
class Animal(object):
def __del__(self):
print("i am 析构方法!") a=Animal()
del a
import time
time.sleep(10) class FileHanlde(object):
path="......."
def __init__(self):
self.f=open(self.path,"r")
def read(self):
return self.f.read()
def __del__(self):
self.f.close() fh=FileHanlde()
fh.read()

析构回收机制

3、item系列:__getitem__\__setitem__\__delitem__

class Animal(object):
def __init__(self,name,age):
self.name=name
self.age=age def __getitem__(self,item):
print('item',item)
return getattr(self,item,None) #getattr判断item属不属于self 属于就返回 不属于就返回None def __setitem__(self, key, value):#可以应用于数据库插入一条数据(写一个功能)
print(key)
print(value) def __delitem__(self, key):
print("del item",key) alex=Animal("alex",45)
# print(alex.name)
# alex.name="xxxx"
# print(alex.name)
print(alex["name"]) # alex.name alex['xxx'] print 得到数据会调用 __getitem__
print(alex["age"]) # alex.age
print(alex['gender'])
print(alex.__dict__)
alex["gender"]="male" #会调用__setitem__ 可以应用于数据库插入一条数据
alex['age'] = 55
print(alex.__dict__)
del alex["xxx"] #会调用__delitem__ # info={"name":"alex","age":"123"}
# info["gneder"]="male"

例子1

class Foo:
def __init__(self,name,addr):
self.name=name
self.addr=addr def __getitem__(self, item):
print(self.__dict__[item]) def __setitem__(self, key, value):
self.__dict__[key]=value
def __delitem__(self, key):
print('del obj[key]时,我执行')
self.__dict__.pop(key)
def __delattr__(self, item):
print('del obj.key时,我执行')
self.__dict__.pop(item) f1=Foo('sb','haxi')
f1['age']=18
f1['age1']=19
print(f1.__dict__)
del f1.age1
del f1['age']
del f1['addr']
print(f1.__dict__)
f1['name']='alex'
print(f1.__dict__)

例子2

4、__getattr__、__setattr__

class Animal(object):
def __init__(self,name,age):
self.name=name
self.age=age def __getattr__(self, item):
print("getattr",item)
return "对象没有%s属性!"%item def __setattr__(self, key, value):
print("空间地址%s为%s属性赋值%s"%(self,key,value))
super().__setattr__(key, value) alex=Animal("alex",56) #实例化过程中__init__回去调用__setattr__
print(alex.gender)
alex.name="李杰"
print(alex.name)

例子

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

class Animal(object):
def __init__(self,name,age):
self.name=name
self.age=age
def run(self):
pass def __call__(self, *args, **kwargs):
print(" i am call 方法!") alex=Animal("alex",12)
print(callable(Animal))
print(callable(Animal.run))
print(callable(alex.run))
print(callable(alex)) # False
alex()

__len__

class A:
def __init__(self):
self.a = 1
self.b = 2 def __len__(self):
return len(self.__dict__)
a = A()
print(len(a))

__hash__

class A:
def __init__(self):
self.a = 1
self.b = 2 def __hash__(self):
return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))

__eq__

class A:
def __init__(self):
self.a = 1
self.b = 2 def __eq__(self,obj):
if self.a == obj.a and self.b == obj.b:
return True
a = A()
b = A()
print(a == b)
class FranchDeck:
ranks = [str(n) for n in range(2,11)] + list('JQKA')
suits = ['红心','方板','梅花','黑桃'] def __init__(self):
self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
for suit in FranchDeck.suits] def __len__(self):
return len(self._cards) def __getitem__(self, item):
return self._cards[item] deck = FranchDeck()
print(deck[0])
from random import choice
print(choice(deck))
print(choice(deck))
class FranchDeck:
ranks = [str(n) for n in range(2,11)] + list('JQKA')
suits = ['红心','方板','梅花','黑桃'] def __init__(self):
self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
for suit in FranchDeck.suits] def __len__(self):
return len(self._cards) def __getitem__(self, item):
return self._cards[item] def __setitem__(self, key, value):
self._cards[key] = value deck = FranchDeck()
print(deck[0])
from random import choice
print(choice(deck))
print(choice(deck)) from random import shuffle
shuffle(deck)
print(deck[:5])
class Person:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex def __hash__(self):
return hash(self.name+self.sex) def __eq__(self, other):
if self.name == other.name and self.sex == other.sex:return True p_lst = []
for i in range(84):
p_lst.append(Person('egon',i,'male')) print(p_lst)
print(set(p_lst))

day06-08面向对象进阶的更多相关文章

  1. python 自动化之路 day 08 面向对象进阶

    面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 面向对象高级语法部分 经典类vs新式类 把下面代码用python2 和python3都执行一下 1 2 ...

  2. Python全栈开发【面向对象进阶】

    Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...

  3. day26、面向对象进阶:多态、封装、反射

    一.多态 什么是多态: 类的继承有两层意义:1.改变 2.扩展 多态就是类的这两层意义的一个具体的实现机. 即:调用不同类实例化的对象,下的相同的方法,实现的过程不一样 python中的标准类型就是多 ...

  4. Python开发【第七篇】:面向对象 和 python面向对象进阶篇(下)

    Python开发[第七篇]:面向对象   详见:<Python之路[第五篇]:面向对象及相关> python 面向对象(进阶篇)   上一篇<Python 面向对象(初级篇)> ...

  5. python基础——面向对象进阶下

    python基础--面向对象进阶下 1 __setitem__,__getitem,__delitem__ 把对象操作属性模拟成字典的格式 想对比__getattr__(), __setattr__( ...

  6. python基础——面向对象进阶

    python基础--面向对象进阶 1.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 ...

  7. 周末班:Python基础之面向对象进阶

    面向对象进阶 类型判断 issubclass 首先,我们先看issubclass() 这个内置函数可以帮我们判断x类是否是y类型的子类. class Base: pass class Foo(Base ...

  8. Python面向对象进阶和socket网络编程-day08

    写在前面 上课第八天,打卡: 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __i ...

  9. 铁乐学python_day24_面向对象进阶1_内置方法

    铁乐学python_day24_面向对象进阶1_内置方法 题外话1: 学习方法[wwwh] what where why how 是什么,用在哪里,为什么,怎么用 学习到一个新知识点的时候,多问问上面 ...

  10. 铁乐学python_day23_面向对象进阶1_反射

    铁乐学python_day23_面向对象进阶1_反射 以下内容大部分摘自博客http://www.cnblogs.com/Eva-J/ isinstance()和issubclass() 两者的返回值 ...

随机推荐

  1. php中的empty()方法

    empty() 判断一个变量是否为“空”,isset() 判断一个变量是否已经设置.empty还会检测变量是否为空.为零.当一个变量值为0,empty() 认为这个变量同等于空,即相当于没有设置.例如 ...

  2. GOF23设计模式之代理模式

    GOF23设计模式之代理模式 核心作用:通过代理,控制对对象的访问.可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理(即:AOP的微观实现) AOP(Asp ...

  3. MySql数据库的一些基本操作---------------SQL语法

    MySql数据库是比较常用的关系型数据库,操作用的是sql语句,下面来说一说MySql的一些基本操作 MySql数据库是一种C/S型的模式,即客户端/服务器端,对应到具体应用上,便是bin目录下的my ...

  4. 【ACM】hdu_1004_Let the Balloon Rise

    Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  5. CentOS 7安装过程

    下载: https://wiki.centos.org/Download 安装过程: 参考: http://tieba.baidu.com/p/3152957061(图片出处)

  6. 【高级算法】禁忌搜索算法解决3SAT问题(C++实现)

    转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46440389 近期梳理,翻出了当年高级算法课程做的题目.禁忌搜索算法解决3SAT问 ...

  7. kafka内置的zookeeper

    kafka 很多说不需要安装zk的是因为他们都使用了kafka自带的zk 至于kafka为什么使用zk,你首先要知道zk的作用, 作为去中心化的集群模式. 需要要消费者知道现在那些生产者(对于消费者而 ...

  8. [Angular] Upgrading to RxJS v6

    This is just a learning blog post, check out the talk. 1. Custom pipeable operators: Custom pipeable ...

  9. cefsharp 获取高度

    G.browser.GetBrowser().MainFrame.ExecuteJavaScriptAsync("$(document).height()"); // Get Do ...

  10. Iterator - 迭代器模式

    定义 提供一个方法顺序訪问一个聚合对象中个各个元素,而又不须要暴露该对象的内部结构. 案例 一个聚合对象.如一个列表List.应该提供一种方法来让别人能够訪问它的元素.而又不用暴露内部结构.迭代器模式 ...