当我们拿到一个对象的引用时,如何知道这个对象是什么类型、有哪些方法呢?

基本类型都可以用type()判断:

print(type(123))
print(type('str'))
print(type(True))

如果一个变量指向函数或者类,也可以用type()判断:

class Animal(object):
pass
a = Animal()
print(type(abs))#指向函数
print(type(a))#指向类

type()函数返回对应的Class类型,如果我们要在if语句中判断,就需要比较两个变量的type类型是否相同:

print(type(123)==type(345))
print(type(13)==int)
#判断基本数据类型可以直接写int,str等
#但如果要判断一个对象是否是函数怎么办?可以使用types模块中定义的常量:
import types
def fn():
pass
print(type(fn)==types.FunctionType)
print(type(abs)==types.BuiltinFunctionType)
print(type(lambda x: x)==types.LambdaType)
print(type((x for x in range(10)))==types.GeneratorType)

使用isinstance()

对于class的继承关系来说,使用type()很不方便,可以使用isinstance()

print(isinstance('a',str))

#基本类型也可以用isinstance()判断:
print(isinstance([1, 2, 3], (list, tuple)))
print(isinstance((1, 2, 3), (list, tuple)))

并且还可以判断一个变量是否是某些类型中的一种,比如下面的代码就可以判断是否是list或者tuple:

总是优先使用isinstance()判断类型,可以将指定类型及其子类“一网打尽”。

使用dir()

如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list

print(dir('abc'))

类似__xxx__的属性和方法在Python中都是有特殊用途的,比如__len__方法返回长度

在Python中,如果你调用len()函数试图获取一个对象的长度,实际上,在len()函数内部,

它自动去调用该对象的__len__()方法,所以,下面的代码是等价的:

print(len('abc'))
print('abc'.__len__())

仅仅把属性和方法列出来是不够的,配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态:

class MyObject(object):
def __init__(self):
self.x = 9
def power(self):
return self.x * self.x
obj = MyObject()

紧接着,可以测试该对象的属性:

print(hasattr(obj,'x'))#有属性'x'吗
print(obj.x)
print(hasattr(obj,'y'))#有属性'y'吗
setattr(obj,'y',19)#设置一个属性y叫19
print(hasattr(obj,'y'))#有属性'y'吗
print(getattr(obj,'y'))#获取属性'y'
#getattr(obj,'z')#获取不存在的属性会报错
print(getattr(obj,'z',404))#可以传入一个值,如果没,就返回值

也可以获得对象的方法:

print(hasattr(obj, 'power')) # 有属性'power'吗?
getattr(obj,'power')#获取属性
fn = getattr(obj,'power')#获取属性'power'并赋值到变量fn
print(fn)# fn指向obj.power
print(fn())#调用fn()与调用obj.power()是一样的

小结

通过内置的一系列函数,我们可以对任意一个Python对象进行剖析,拿到其内部的数据。

要注意的是,只有在不知道对象信息的时候,我们才会去获取对象信息

sum = obj.x + obj.y#可以直接这样写,就绝不要下面的写法
sum = getattr(obj, 'x') + getattr(obj, 'y')

一个正确的例子

def readImage(fp):
if hasattr(fp, 'read'):
return readData(fp)
return None

假设我们希望从文件流fp中读取图像,我们首先要判断该fp对象是否存在read方法,如果存在,则该对象是一个流,如果不存在,则无法读取。hasattr()就派上了用场。

最新文章

  1. WCF学习系列汇总
  2. 【Android】[转] Android屏幕旋转使用OrientationEventListener的监听
  3. PHP魔术常量
  4. OS X EI Capitan安装refind时出现Could not set boot device property: 0xe00002bc
  5. RoundedImageView,实现圆形、圆角矩形的注意事项
  6. POJ2226 Muddy Fields
  7. RHEL 5 安装phpqrcode生成二维码
  8. NYOJ-253 凸包
  9. Android(java)学习笔记123:Clock app编写报错01
  10. 【动态规划】Vijos P1121 马拦过河卒
  11. Tomcat8 + Redis实现session集中管理
  12. 【深度学习】L1正则化和L2正则化
  13. pep 8 规范的一些记录
  14. Leetcode 存在重复元素 (219,220)
  15. 洛谷P3381 最小费用最大流
  16. linux下的crontab安装及简单使用
  17. Linux学习笔记7
  18. Django框架详细介绍---模板系统
  19. BASEDIR
  20. c# 正则格式化文本防止SQL注入

热门文章

  1. CPP相关的常见错误(更新ing)
  2. CF603E Pastoral Oddities
  3. json.stringify和json.parse,序列化和反序列化
  4. echarts 取消图例上的点击事件和图表上鼠标滑过点击事件
  5. 线程Thread类
  6. 33. Search in Rotated Sorted Array & 81. Search in Rotated Sorted Array II
  7. docker存储与网络
  8. 易捷支付完整业务流程的lr脚本编写
  9. 无法使用备份文件 'D:\20160512.bak',因为原先格式化该文件时所用扇区大小为 512,而目前所在设备的扇区大小为 4096
  10. Node remains in conflict,svn冲突解决办法