Python 简明教程

Python - Reflection

在面向对象编程中, reflection 指的是提取正在使用的任何对象信息的能力。你可以了解对象的类型、它是否为其他任何类的子类、它的 attributes ,以及更多内容。Python 的标准库有若干函数可以反映对象的各个属性。 Reflection 有时也称为 introspect

以下是 Python 中的反射函数列表 −

  1. type() Function

  2. isinstance() Function

  3. issubclass() Function

  4. callable() Function

  5. getattr() Function

  6. setattr() Function

  7. hasattr() Function

  8. dir() Function

The type() Function

我们已经多次使用该函数。它告诉你对象属于哪个类。

Example

以下语句打印不同内置数据类型对象的相应类

print (type(10))
print (type(2.56))
print (type(2+3j))
print (type("Hello World"))
print (type([1,2,3]))
print (type({1:'one', 2:'two'}))

在这里,你会得到以下 output

<class 'int'>
<class 'float'>
<class 'complex'>
<class 'str'>
<class 'list'>
<class 'dict'>

让我们验证一下用户自定义类对象的类型 -

class test:
   pass

obj = test()
print (type(obj))

它将生成以下 output

<class '__main__.test'>

The isinstance() Function

这是 Python 中的另一个内置函数,它可以确定对象是否是给定类的实例。

Syntax

isinstance(obj, class)

此函数总是返回一个 Boolean value ,如果对象确实属于给定类,则为 true;否则为 false。

Example

以下语句返回 True -

print (isinstance(10, int))
print (isinstance(2.56, float))
print (isinstance(2+3j, complex))
print (isinstance("Hello World", str))

它将生成以下 output

True
True
True
True

相反,这些语句打印 False。

print (isinstance([1,2,3], tuple))
print (isinstance({1:'one', 2:'two'}, set))

它将生成以下 output

False
False

你也可以使用用户自定义类进行检查

class test:
   pass

obj = test()
print (isinstance(obj, test))

它将生成以下 output

True

在 Python 中,即使类也是对象。所有类都是 object 类对象。这可以通过以下代码验证 -

class test:
   pass

print (isinstance(int, object))
print (isinstance(str, object))
print (isinstance(test, object))

以上所有 print 语句都打印 True。

The issubclass() Function

此函数检查某个类是否另一个类的子类。它属于类,而不是它们的实例。

如前所述,所有 Python 类都是 object 类的子类。因此,以下 print 语句的输出对于所有类而言都是 True。

class test:
   pass

print (issubclass(int, object))
print (issubclass(str, object))
print (issubclass(test, object))

它将生成以下 output

True
True
True

The callable() Function

如果对象调用某个过程,则该对象是可调用的。执行某个过程的 Python function 是可调用对象。因此,callable(function) 返回 True。任何函数、内置函数、用户自定义函数或 method 都可以调用。诸如 int、str 等内置 data types 的对象不可调用。

Example

def test():
   pass

print (callable("Hello"))
print (callable(abs))
print (callable(list.clear([1,2])))
print (callable(test))

string 对象不可调用。但 abs 是一个可调用的函数。列表的 pop 方法可调用,但 clear() 实际上是对函数的调用,而不是函数对象,因此不可调用。

它将生成以下 output

False
True
True
False
True

如果类实例具有 call() 方法,则该实例可调用。在下面的示例中,test 类包括 call() 方法。因此,它的对象可以用作我们调用某个函数的情况。因此,具有 call() 函数的类的对象可调用。

class test:
   def __init__(self):
      pass
   def __call__(self):
      print ("Hello")

obj = test()
obj()
print ("obj is callable?", callable(obj))

它将生成以下 output

Hello
obj is callable? True

The getattr() Function

getattr() 内置函数会检索对象的命名属性值。

Example

class test:
   def __init__(self):
      self.name = "Manav"

obj = test()
print (getattr(obj, "name"))

它将生成以下 output

Manav

The setattr() Function

setattr() 内置函数会向对象添加一个新属性并赋予它一个值。它还可以更改现有属性的值。

在下面的示例中,test 类的对象具有单个属性 − name。我们使用 setattr() 来添加 age 属性并修改 name 属性的值。

class test:
   def __init__(self):
      self.name = "Manav"

obj = test()
setattr(obj, "age", 20)
setattr(obj, "name", "Madhav")
print (obj.name, obj.age)

它将生成以下 output

Madhav 20

The hasattr() Function

此内置函数在给定对象参数可以使用给定属性时返回 True,否则返回 False。我们使用相同的测试类,然后检查它是否有某个属性。

class test:
   def __init__(self):
      self.name = "Manav"

obj = test()
print (hasattr(obj, "age"))
print (hasattr(obj, "name"))

它将生成以下 output

False
True

The dir() Function

如果此内置函数在没有参数的情况下被调用,则返回当前作用域中的名称。对于任何作为参数的对象,它返回给定对象属性的列表以及从该对象可到达的属性。

  1. For a module object − 该函数返回模块的属性。

  2. For a class object − 该函数返回其属性,以及递归返回其基类的属性。

  3. For any other object − 其属性,其类的属性,以及递归返回其类的基类的属性。

Example

print ("dir(int):", dir(int))

它将生成以下 output

dir(int): ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__getstate__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'bit_count', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

Example

print ("dir(dict):", dir(dict))

它将生成以下 output

dir(dict): ['__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__ior__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__ror__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

Example

class test:
   def __init__(self):
      self.name = "Manav"

obj = test()
print ("dir(obj):", dir(obj))

它将生成以下 output

dir(obj): ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name']