python获取对象属性的几种方法

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

1.使用type()

首先,我们来判断对象类型,使用type()函数:

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

>>> type(123)
<class 'int'>
>>> type('str')
<class 'str'>
>>> type(None)
<type(None) 'NoneType'>

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

>>> type(abs)
<class 'builtin_function_or_method'>
>>> type(a)

<class '__main__.Animal'>

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

>>> type(123)==type(456)
True
>>> type(123)==int
True
>>> type('abc')==type('123')
True
>>> type('abc')==str
True
>>> type('abc')==type(123)

False

判断基本数据类型可以直接写int,str等,但如果要判断一个对象是否是函数怎么办?可以使用types模块中定义的常量:

>>> import types
>>> def fn():
...     pass
...
>>> type(fn)==types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType

True

2.使用isinstance()

对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数。

我们回顾上次的例子,如果继承关系是:

object -> Animal -> Dog -> Husky

那么,isinstance()就可以告诉我们,一个对象是否是某种类型。先创建3种类型的对象:

>>> a = Animal()
>>> d = Dog()

>>> h = Husky()

然后,判断:

>>> isinstance(h, Husky)

True

没有问题,因为h变量指向的就是Husky对象。

再判断:

>>> isinstance(h, Dog)

True

h虽然自身是Husky类型,但由于Husky是从Dog继承下来的,所以,h也还是Dog类型。换句话说,isinstance()判断的是一个对象是否是该类型本身,或者位于该类型的父继承链上。

因此,我们可以确信,h还是Animal类型:

>>> isinstance(h, Animal)

True

同理,实际类型是Dog的d也是Animal类型:

>>> isinstance(d, Dog) and isinstance(d, Animal)

True

但是,d不是Husky类型:

>>> isinstance(d, Husky)

False

能用type()判断的基本类型也可以用isinstance()判断:

>>> isinstance('a', str)
True
>>> isinstance(123, int)
True
>>> isinstance(b'a', bytes)

True

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

>>> isinstance([1, 2, 3], (list, tuple))
True
>>> isinstance((1, 2, 3), (list, tuple))

True

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

3.使用dir()

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

>>> dir('ABC')

['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']

类似__xxx__的属性和方法在Python中都是有特殊用途的,比如__len__方法返回长度。在Python中,如果你调用len()函数试图获取一个对象的长度,实际上,在len()函数内部,它自动去调用该对象的__len__()方法,所以,下面的代码是等价的:

>>> len('ABC')
3
>>> 'ABC'.__len__()

3

我们自己写的类,如果也想用len(myObj)的话,就自己写一个__len__()方法:

>>> class MyDog(object):
...     def __len__(self):
...         return 100
...
>>> dog = MyDog()
>>> len(dog)

100

剩下的都是普通属性或方法,比如lower()返回小写的字符串:

>>> 'ABC'.lower()

'abc'

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

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

>>> obj = MyObject()

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

>>> hasattr(obj, 'x') # 有属性'x'吗?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有属性'y'吗?
False
>>> setattr(obj, 'y', 19) # 设置一个属性'y'
>>> hasattr(obj, 'y') # 有属性'y'吗?
True
>>> getattr(obj, 'y') # 获取属性'y'
19
>>> obj.y # 获取属性'y'

19

如果试图获取不存在的属性,会抛出AttributeError的错误:

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流群:711312441
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
>>> getattr(obj, 'z') # 获取属性'z'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>

AttributeError: 'MyObject' object has no attribute 'z'

可以传入一个default参数,如果属性不存在,就返回默认值:

>>> getattr(obj, 'z', 404) # 获取属性'z',如果不存在,返回默认值404

404

也可以获得对象的方法:

>>> hasattr(obj, 'power') # 有属性'power'吗?
True
>>> getattr(obj, 'power') # 获取属性'power'
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn
>>> fn # fn指向obj.power
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn() # 调用fn()与调用obj.power()是一样的
81

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python获取对象属性的几种方法 - Python技术站

(0)
上一篇 2023年4月2日
下一篇 2023年4月2日

相关文章

  • python3教程:*和**的打包和解包的用法

    一. 打包参数 1. * 的作用:在函数定义中,收集所有的位置参数到一个新的元组,并将这个元组赋值给变量args >>> def f(*args): print(args) >>> f() () >>> f(1) (1,) >>> f(1, 2, 3, 4) (1, 2, 3, 4) &…

    Python开发 2023年4月2日
    00
  • Python迭代器是啥?

    迭代器:迭代的工具。迭代是更新换代,如你爷爷生了你爹,你爹生了你,迭代也可以说成是重复,并且但每一次的重复都是基于上一次的结果来的。如计算机中的迭代开发,就是基于软件的上一个版本更新。以下代码就不是迭代,它只是单纯的重复 while True: print(‘*’*10) 一、可迭代对象 python中一切皆对象,如 x = 1 name = ‘nick’ …

    Python开发 2023年3月31日
    00
  • python学习:重用父类功能的两种方式

    在子类派生的新方法中如何重用父类的功能方式一:指名道姓调用某一个类下的函数=》不依赖于继承关系 class OldboyPeople: def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def f1(self): print(‘%s say hello’ %se…

    Python开发 2023年4月2日
    00
  • Http和Https的区别?

    1.HTTP是什么? http是超文本传输协议用来在web浏览器和网站服务器之间传递数据信息,http以明文的方式发送内容,不提供任何方式的数据加密,如果攻击者截获了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。为了解决http协议的这一缺陷,需要使用另一种协议:安…

    Python开发 2023年4月2日
    00
  • python教程:函数的return语句运用

    return语句用于退出函数,向调用方返回一个表达式。 return在不带参数的情况下(或者没有写return语句),默认返回None。 None是一个特殊的值,它的数据类型是NoneType。NoneType是Python的特殊类型,它只有一个取值None。 它不支持任何运算也没有任何内建方法,和任何其他的数据类型比较是否相等时永远返回false,也可以将…

    Python开发 2023年4月2日
    00
  • Python中的关键字的用法

    Python有哪些关键字 Python常用的关键字 and, del, from, not, while, as, elif, global, or, with, assert, else, if, pass, yield, break, except, import, print, class, exec, in, raise, contiue, fina…

    Python开发 2023年3月31日
    00
  • Python类的多态和多态性

    一、多态 多态指的是一类事物有多种形态,一个类有很多个子类,因而多态的概念是基于继承的 序列数据类型有多种形态:字符串,列表,元组 动物有多种形态:人,狗,猪 1.动物的多种形态 # 动物有多种形态:人类、猪、狗 class Animal: def run(self): # 子类约定俗称的必须实现这个方法 raise AttributeError(‘子类必须…

    Python开发 2023年4月2日
    00
  • Python中高阶函数与装饰器教程

    1高阶函数 1.1 数学概念 回顾下数学知识: y=f(x) 这是最开始接触的普通函数 y=g(f(x)) 这个就是我们接触到的高阶函数 在数学和计算机科学中,高阶函数至少应当是满足下面一个条件的函数: 1)接受一个或者多个函数作为参数 2)输出一个函数 程序中我们的高阶函数也类似 示例计数器的函数: def counter(base): def inc(s…

    Python开发 2023年3月31日
    00
合作推广
合作推广
分享本页
返回顶部