开放的编程资料库

当前位置:我爱分享网 > Python教程 > 正文

Python 自省

在本文中,我们讨论了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模块的executableargvbyteorder属性。

>>> 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类的子类。ObjectWall也是它们自己的子类。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教程。

未经允许不得转载:我爱分享网 » Python 自省

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏