isinstance和issubclass

isinstance(obj,cls)检查是否obj是否是类 cls 的对象或者子类的对象

class Foo(object):
pass
class bar(Foo):
  pass
obj = Foo() sinstance(obj, Foo) == True

issubclass(sub, super)检查sub类是否是 super 类的派生类

class Foo(object):
pass class Bar(Foo):
pass issubclass(Bar, Foo)

反射

1 什么是反射

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

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

四个可以实现自省的函数

下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

def hasattr(*args, **kwargs): # real signature unknown
"""
Return whether the object has an attribute with the given name. This is done by calling getattr(obj, name) and catching AttributeError.
"""
pass

hasattr

def getattr(object, name, default=None): # known special case of getattr
"""
getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
"""
pass

getattr

def setattr(x, y, v): # real signature unknown; restored from __doc__
"""
Sets the named attribute on the given object to the specified value. setattr(x, 'y', v) is equivalent to ``x.y = v''
"""
pass

setattr

def delattr(x, y): # real signature unknown; restored from __doc__
"""
Deletes the named attribute from the given object. delattr(x, 'y') is equivalent to ``del x.y''
"""
pass

delattr

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,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__)
print(obj.show_name(obj)) #删除属性
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111')#不存在,则报错 print(obj.__dict__)

四个方法的使用演示

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')()

__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

__del__

析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

class Foo:

    def __del__(self):
print('执行我啦') f1=Foo()
del f1
print('------->') #输出结果
执行我啦
------->

简单示范

item系列

__getitem__\__setitem__\__delitem__

class Foo:
def __init__(self,name):
self.name=name 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')
f1['age']=18
f1['age1']=19
del f1.age1
del f1['age']
f1['name']='alex'
print(f1.__dict__)
 

__new__

class A:
def __init__(self):
self.x = 1
print('in init function')
def __new__(cls, *args, **kwargs):
print('in new function')
return object.__new__(A, *args, **kwargs) a = A()
b = A()
print(id(a),id(b)) # 不一样的值,每一个对象都是独立的
class Singleton:
def __new__(cls, *args, **kw): # __new__方法,创建对象
if not hasattr(cls, '_instance'): # 如果这个对象Singleton没有_instance属性
cls._instance = object.__new__(cls, *args, **kw) # 给这个Singleton创建一个_instance变量,并且把这个新对象赋予给这个变量
return cls._instance # 有_instance属性,就返回这个对象 one = Singleton()
two = Singleton() # 第二次的时候,_instance有这个属性了,返回了这个对象 two.a = 3
print(one.a)
#
# one和two完全相同,可以用id(), ==, is检测
print(id(one))
#
print(id(two))
#
print(one == two)
# True
print(one is two)

单例模式

__call__

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

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

class Foo:

    def __init__(self):
pass def __call__(self, *args, **kwargs): print('__call__') obj = Foo() # 执行 __init__
obj() # 执行 __call__

__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)
from collections import namedtuple
Card = namedtuple('Card',['rank','suit']) 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 def __call__(self, *args, **kwargs):
return self._cards deck = FranchDeck()
print(deck) # 类对象
print(deck._cards) # 得到52张牌 [Card(rank='2', suit='红心'), Card(rank='2', suit='方板'), Card(rank='2', suit='梅花'), Card(rank='2', suit='黑桃')....]
print(len(deck)) #
print(deck[0]) # 取第一张牌,有序拿牌 from random import choice # CHIOCE 依赖于__len__ __getitem__ len给索引,getitem取值
print(choice(deck))
print(choice(deck)) from random import shuffle # 洗牌 __len__ __setitem__
shuffle(deck)
print(deck[0]) print(deck[0]) # __call__ 已经乱序

纸牌游戏

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 == self.sex:return True p_lst = []
for i in range(84):
p_lst.append(Person('egon',i,'male')) print(p_lst)
print(set(p_lst))
# 如果名字和性别相同,我们判定他们是同一个人

一道面试题

python开发面向对象进阶:反射&内置函数的更多相关文章

  1. Python 面向对象 (补充) , 反射 , 内置函数

    面向对象中内置函数 issubclass方法: 检查第一个参数是否是第二个参数的子子孙孙类     返回  :   是一个布尔值 class Base(object): pass class Foo( ...

  2. Python进阶(五)----内置函数Ⅱ 和 闭包

    Python进阶(五)----内置函数Ⅱ 和 闭包 一丶内置函数Ⅱ ####内置函数#### 特别重要,反复练习 ###print() 打印输入 #sep 设定分隔符 # end 默认是换行可以打印到 ...

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

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

  4. python基础12_匿名_内置函数

    一个二分查找的示例: # 二分查找 示例 data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35, 36, ...

  5. 【python】dir(__builtins__)查看python中所用BIF(内置函数)

    dir(__builtins__)查看python中所用BIF(内置函数)

  6. 查看python内部模块命令,内置函数,查看python已经安装的模块命令

    查看python内部模块命令,内置函数,查看python已经安装的模块命令 可以用dir(modules) 或者用 pip list或者用 help('modules') 或者用 python -m  ...

  7. Python学习(八) —— 内置函数和匿名函数

    一.递归函数 定义:在一个函数里调用这个函数本身 递归的最大深度:997 def func(n): print(n) n += 1 func(n) func(1) 测试递归最大深度 import sy ...

  8. python开发函数进阶:内置函数

    一,内置函数 #内置的模块#拿过来直接就用的:内置的函数 #!/usr/bin/env python #_*_coding:utf-8_*_ #内置的模块 #拿过来直接就用的:内置的函数 #作用域相关 ...

  9. python之路:进阶篇 内置函数

     li = [11, 22, 33] news = map(  li = [100, 2200, 3300] news = map(  [13, 24, 35] [11, 11, 11] [22, 4 ...

  10. python大法好——递归、内置函数、函数进阶

    1.递归(自己干自己) def fun(n): n=n/2 print(n) if(n>2) fun(n) #函数调用 fun(10) 结果是5 2 1 0 递归的执行过程:递归执行到最里面一层 ...

随机推荐

  1. python学习笔记(arange函数与linspace函数)

    上一篇提及到matplotlib模块.其中会涉及到numpy模块科学计数 这里总结两个数组生成函数 arange 与 linspace: #!/usr/bin/env python # -*- cod ...

  2. java中的char类型所占空间

    java中统一使用unicode编码,所以每个字符都是2个字节16位.unicode包括中文,所以对String类计算长度的时候,一个中文和一个英文都是一个长度.String voice = &quo ...

  3. java开发工具idea,在install时候报错The packaging for this project did not assign a file to the build artifact

    intellij中install报错:The packaging for this project did not assign a file to the build artifact 原因是run ...

  4. mongodb底层存储和索引原理——本质是文档数据库,无表设计,同时wiredTiger存储引擎支持文档级别的锁,MMAPv1引擎基于mmap,二级索引(二级是文档的存储位置信息『文件id + 文件内offset 』)

    MongoDB是面向文档的数据库管理系统DBMS(显然mongodb不是oracle那样的RDBMS,而仅仅是DBMS). 想想一下MySQL中没有任何关系型数据库的表,而由JSON类型的对象组成数据 ...

  5. opencv:图像的腐蚀和膨胀

    1.图像的腐蚀 图像的腐蚀和膨胀都是相对于像素值高(白色方向)说的,腐蚀简单的说就是白色”被腐蚀“了,也就是像素值低(黑色方向)的变多,白色变少. 腐蚀的原理是利用一个内核对图像进行卷积(扫描),内核 ...

  6. monkey 原理,环境搭建、命令详解

    一.monkey测试的相关的原理 monkey测试的原理就是利用socket通讯的方式来模拟用户的按键输入,触摸屏输入,手势输入等,看设备多长时间会出异常.当Monkey程序在模拟器或设备运行的时候, ...

  7. LeetCode OJ:Next Permutation(下一排列)

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

  8. TreeView.ImageSet 属性

    TreeView.ImageSet 属性 .NET Framework 2.0         注意:此属性在 .NET Framework 2.0 版中是新增的. 获取或设置用于 TreeView  ...

  9. C#基础知识梳理系列

    1. 这个系列深入的从IL层面谈了C#各种基本知识的本质,十分值得学习: http://www.cnblogs.com/solan/category/398748.html

  10. git pull VS git fetch&merge

    使用git fetch和git pull都可以更新远程仓库的代码到本地,但是它们之间还是有区别. git fetch  git fetch origin master git log -p maste ...