Python 获取对象的属性和方法—dir 函数

Posted Gnbp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 获取对象的属性和方法—dir 函数相关的知识,希望对你有一定的参考价值。

工作中,我们使用一些之前没用到过的模块,使用时需要了解一下这个模块中的一些类的方法或属性,怎么做呢?目前我比较常用的两款IDE“Pycharm”和“VSCode”,都可以通过先导包,然后通过“Ctrl+鼠标左键”,进入源码后观看并膜拜一下大神们的代码,当然也可以进入我们在项目中自己所定义的,然后进行快速修改,真的是很方便呢。但是有的时候,我们使用的环境没有这类的IDE,那该怎么学习我们要用的这些类方法和属性呢?方法当然很多,无论是小白,还是大神,百度谷歌大法都是比较快速和方便的。但是对于一些刚开源的或者是我们自己定义的呢,这里我们就聊聊Python 中的内建函数——dir 函数

 

首先可以先通过简单的源码解读,可以得知:

1.他的返回值是一个元素为字符串的列表

 

2.当传入一个模块对象时,返回的是模块里面所有的属性(变量名和方法)

我在function_use 这个文件夹或者包中创建了一个模块(demo01.py),内容随便定义几个变量和函数及类,如:

 1 a = 10
 2 b = test
 3 
 4 def c(x):
 5     print(x)
 6 
 7 class D(object):
 8     def __init__(self):
 9         self.name = name
10         self.age = 18
11 
12     def get_name(self):
13         return self.name
14 
15 class E(D):
16     pass

然后再创建一个模块(demo02.py),并在"demo02.py"中引用"demo01.py“,然后打印dir(demo01),如:

1 from function_use import demo01
2 
3 print(dir(demo01))
4 
5 
6 [D, E, __builtins__, __cached__, __doc__, __file__, __loader__, __name__, __package__, __spec__, a, b, c]

 

3.当传入的对象是一个类时,返回这个类及其所有父类(包括父类的父类)的属性和方法

就上面的例子,无论是在当前模块“demo01.py”下面调用:

1 ...
2 if __name__ == __main__:
3     print(dir(D))
4 
5 [__class__, __delattr__, __dict__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __gt__, __hash__, __init__, __le__, __lt__, __module__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__, __weakref__, get_name]

还是在“demo02.py” 中引用的调用

1 from function_use import demo01
2 
3 # print(dir(demo01))
4 print(dir(demo01.D))
5 
6 [__class__, __delattr__, __dict__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __gt__, __hash__, __init__, __le__, __lt__, __module__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__, __weakref__, get_name]

可以看出,结果是一样的。


4.当传入的对象是其他的时候(照我的理解,这个其他对象,就是一个实例对象),则返回这个实例对象的属性和方法,实例对象类的属性和方法,以及这个类的所有基类的属性和方法

相对于第三种情况(传入的对象是一个类时)其实只是多了这个实例对象的属性,感觉绕的话,就看下面的例子:
老样子,在”demo01.py“ 里面

1 ...
2 if __name__ == __main__:
3     e = E()
4     print(dir(e))
5 
6 [__class__, __delattr__, __dict__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __gt__, __hash__, __init__, __le__, __lt__, __module__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__, __weakref__, age, get_name, name]

或者在”demo02.py“ 里面

1 from function_use import demo01
2 
3 # print(dir(demo01))
4 e = demo01.E()
5 print(dir(e))
6 
7 [__class__, __delattr__, __dict__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __gt__, __hash__, __init__, __le__, __lt__, __module__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__, __weakref__, age, get_name, name]

可以看到,只是多了E 的实例对象的两个属性“age” 和“name”

 


===================问题分割线===================

这里就有一个待解决的问题,就上面的例子,我尝试了在demo01.py 模块的D 这个类里面加了一个类方法及类属性

技术图片
 1 a = 10
 2 b = test
 3 
 4 
 5 def c(x):
 6     print(x)
 7 
 8 
 9 class D(object):
10     dd = 123
11 
12     def __init__(self):
13         self.name = name
14         self.age = 18
15 
16     def get_name(self):
17         return self.name
18 
19     @classmethod
20     def print_x(cls):
21         print("x")
22 
23 
24 class E(D):
25     pass
26 
27 
28 if __name__ == __main__:
29     # e = E()
30     # print(dir(e))
31     print(dir(E))
32     E.print_x()
33     # print(E.get_name())
34 
35 
36 [__class__, __delattr__, __dict__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __gt__, __hash__, __init__, __le__, __lt__, __module__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__, __weakref__, dd, get_name, print_x]
37 
38 x # E.print_x()
View Code

这都没问题,但是我去调用dir 函数返回的“get_name” 函数时,却提示我必须要传入一个必传的参数“self”这样就需要
print(E.get_name(E()))了,但是这样的话,为什么这个方法可以出现在dir(E)的返回值里面呢?
有点晕
===================问题分割线===================

 

 

说完这个函数的返回值,我们再聊聊其中具体的内容,这里用自定义的例子不好说明,就搬来廖老师的例子吧

首先对一个字符串对象,比如“ABC” 使用dir()函数,查看他的所有属性和方法

1 print(dir("ABC"))
2 
3 [__add__, __class__, __contains__, __delattr__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __getitem__, __getnewargs__, __gt__, __hash__, __init__, __iter__, __le__, __len__, __lt__, __mod__, __mul__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__, __rmod__, __rmul__, __setattr__, __sizeof__, __str__, __subclasshook__, capitalize, casefold, center, count, encode, endswith, expandtabs, find, format, format_map, index, isalnum, isalpha, isdecimal, isdigit, isidentifier, islower, isnumeric, isprintable, isspace, istitle, isupper, join, ljust, lower, lstrip, maketrans, partition, replace, rfind, rindex, rjust, rpartition, rsplit, rstrip, split, splitlines, startswith, strip, swapcase, title, translate, upper, zfill]

可以看出来,字符串对象的属性和方法还是很多的,类似__xx__的属性和方法在Python 中都是有特殊用途的,比如__len__方法返回长度。在Python 中,如果你调用len() 函数试图获得一个对象的长度,实际上,在len() 函数内部,它自动去调用该对象的__len__() 方法,所以得到两个结论:

1.下面的代码是等价的

1 print(len("ABC")) # 3
2 print("ABC".__len__()) # 3

 

2.对一个对象使用dir 函数,返回的列表里面,如果没有__len__ 方法,我们去对这个对象使用len 函数,就会报TypeError 的错

比如对整数类型使用len 函数,或者是上面我们"demo01.py" 里面的"e" 使用len 函数,如果我们想用len(e) 的话,就要自己写一个__len__() 方法:

 1 class D(object):
 2     dd = 123
 3 
 4     def __init__(self):
 5         self.name = name
 6         self.age = 18
 7 
 8     def __len__(self):
 9         return 100
10 
11     def get_name(self):
12         return self.name
13 
14     @classmethod
15     def print_x(cls):
16         print("x")
17 
18 
19     class E(D):
20         pass
21 
22 if __name__ == __main__:
23     e = E()
24     print(len(e))         # 100

 

除了这些“__xx__” 特殊格式的方法,剩下的都是普通属性或方法,比如lower() 返回小写的字符串

1 print("ABC".lower()) # ‘abc‘

 未完

以上是关于Python 获取对象的属性和方法—dir 函数的主要内容,如果未能解决你的问题,请参考以下文章

python学习笔记011——内置函数dir()

Python dir() 函数

python函数回顾:dir()

python dir()详解

Python3 dir() 函数

3.2面向对象基础语法