在本文中,我们讨论了Python中的内省。
内省是一种自我检查的行为。在计算机编程中,内省是在运行时确定对象的类型或属性的能力。Python编程语言非常支持内省。Python中的一切都是对象。Python中的每个对象都可能有属性和方法。通过使用内省,我们可以动态检查Python对象。
Python目录函数
dir
函数返回属于对象的属性和方法的排序列表。
>>> dir(()) ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
这里我们看到元组对象的dir
函数的输出。
>>> print(().__doc__) tuple() -> empty tuple tuple(iterable) -> tuple initialized from iterable's items If the argument is a tuple, the return value is the same object.
我们的调查表明元组对象有一个__doc__
属性。
#!/usr/bin/python # direx.py import sys class MyObject(object): def __init__(self): pass def examine(self): print(self) o = MyObject() print(dir(o)) print(dir([])) print(dir({})) print(dir(1)) print(dir()) print(dir(len)) print(dir(sys)) print(dir("String"))
该示例使用dir
函数检查多个对象:用户定义的对象、本机数据类型、函数、字符串或数字。
没有任何参数,dir
返回当前范围内的名称。
>>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__'] >>> import sys >>>import math, os >>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'math', 'sys']
我们在包含一些模块之前和之后执行dir
函数。
Python类型函数
type
函数返回对象的类型。
#!/usr/bin/python # typefun.py import sys def function(): pass class MyObject(object): def __init__(self): pass o = MyObject() print(type(1)) print(type("")) print(type([])) print(type({})) print(type(())) print(type(object)) print(type(function)) print(type(MyObject)) print(type(o)) print(type(sys))
该示例将各种类型的对象打印到控制台屏幕。
$ ./typefun.py <class 'int'> <class 'str'> <class 'list'> <class 'dict'> <class 'tuple'> <class 'type'> <class 'function'> <class 'type'> <class '__main__.MyObject'> <class 'module'>
id()函数
id
返回一个对象的特殊id。
#!/usr/bin/python # idfun.py import sys def fun(): pass class MyObject(object): def __init__(self): pass o = MyObject() print(id(1)) print(id("")) print(id({})) print(id([])) print(id(sys)) print(id(fun)) print(id(MyObject)) print(id(o)) print(id(object))
代码示例打印各种对象的ID,包括内置的和自定义的。
$ ./idfun.py 10914368 139696088742576 139696087935944 139696065155784 139696088325640 139696088244296 21503992 139696087910776 10738720
Python系统模块
sys
模块提供对解释器使用或维护的系统特定变量和函数的访问,以及对与解释器交互作用强的函数的访问。该模块允许我们查询Python环境。
>>> import sys >>> sys.version '3.10.6 (main, Aug 10 2022, 11:40:04) [GCC 11.3.0]' >>> sys.platform 'linux' >>> sys.path ['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/home/jano/.local/lib/python3.10/site-packages', '/usr/local/lib/python3.10/dist-packages', '/usr/lib/python3/dist-packages']
在上面的代码中,我们检查了Python版本、平台和搜索路径位置。
我们还可以使用dir
函数来获取sys
模块的变量和函数的完整列表。
>>> sys.executable '/usr/bin/python3' >>> sys.argv [''] >>> sys.byteorder 'little'
该示例展示了sys
模块的executable
、argv
和byteorder
属性。
>>> sys.executable '/usr/bin/python'
可执行文件是一个字符串,在有意义的系统上为Python解释器提供可执行二进制文件的名称。
>>> sys.argv ['']
这给出了传递给Python脚本的命令行参数列表。
>>> sys.byteorder 'little'
字节顺序是本机字节顺序的指示器。这将在big-endian(最高有效字节优先)平台上具有值“big”,在little-endian(最低有效字节优先)平台上具有“little”值。
其他自省
接下来我们展示检查Python对象的各种其他方法。
#!/usr/bin/python # attr.py def fun(): pass print(hasattr(object, '__doc__')) print(hasattr(fun, '__doc__')) print(hasattr(fun, '__call__')) print(getattr(object, '__doc__')) print(getattr(fun, '__doc__'))
hasattr
函数检查对象是否具有属性。getattr
函数返回属性的内容(如果有的话)。
$ ./attr.py True True True The most base type None
isinstance
函数检查对象是否是特定类的实例。
>>> print(isinstance.__doc__) Return whether an object is an instance of a class or of a subclass thereof. A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B) or ...`` etc.
我们可以交互地获取函数的描述。
#!/usr/bin/python # instance.py class MyObject(object): def __init__(self): pass o = MyObject() print(isinstance(o, MyObject)) print(isinstance(o, object)) print(isinstance(2, int)) print(isinstance('str', str))
众所周知,Python中万物皆对象;偶数和字符串。object
是Python中所有对象的基本类型。
$ ./instance.py True True True True
issubclass
函数检查特定类是否是另一个类的派生类。
#!/usr/bin/python # subclass.py class Object(object): def __init__(self): pass class Wall(Object): def __init__(self): pass print(issubclass(Object, Object)) print(issubclass(Object, Wall)) print(issubclass(Wall, Object)) print(issubclass(Wall, Wall))
在我们的代码示例中,Wall
类是Object
类的子类。Object
和Wall
也是它们自己的子类。Object
类不是Wall
类的子类。
$ ./subclass.py True False True True
__doc__
属性提供了一些关于对象的文档,__name__
属性保存了对象的名称。
#!/usr/bin/python # namedoc.py def noaction(): '''A function, which does nothing''' pass funcs = [noaction, len, str] for i in funcs: print(i.__name__) print(i.__doc__) print("-" * 75)
在我们的示例中,我们创建了一个包含三个函数的列表:一个自定义函数和两个本机函数。我们遍历该列表并打印__name__
和__doc__
属性。
$ ./namedoc.py noaction A function, which does nothing --------------------------------------------------------------------------- len Return the number of items in a container. --------------------------------------------------------------------------- str str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'. ---------------------------------------------------------------------------
最后,还有一个callable
函数。该函数检查对象是否为可调用对象(函数)。
#!/usr/bin/python # callable.py class Car(object): def setName(self, name): self.name = name def fun(): pass c = Car() print(callable(fun)) print(callable(c.setName)) print(callable([])) print(callable(1))
在代码示例中,我们检查三个对象是否可调用。
print(callable(fun)) print(callable(c.setName))
fun
函数和setName
方法是可调用的。(方法是绑定到对象的函数。)
$ ./callable.py True True False False
在这
检查
模块。
列出所有Python教程。