Python - 反射
在面向对象编程中,reflection(反射)指的是提取正在使用中的任何对象信息的特性。您可以了解对象的类型、它是否是其他 class 的子类、它的属性是什么,以及更多信息。Python 的标准库提供了几个函数来反射对象的不同属性。Reflection 有时也被称为 introspect(内省)。
以下是 Python 中的反射函数列表 −
- type() Function
- isinstance() Function
- issubclass() Function
- callable() Function
- getattr() Function
- setattr() Function
- hasattr() Function
- dir() Function
type() 函数
我们已经多次使用过这个函数。它告诉您对象属于哪个 class。
示例
以下语句打印不同内置数据类型对象的相应 class
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'}))
这里,您将得到以下 输出 −
<class 'int'> <class 'float'> <class 'complex'> <class 'str'> <class 'list'> <class 'dict'>
让我们验证用户定义 class 的对象类型 −
class test: pass obj = test() print (type(obj))
它将产生以下 输出 −
<class '__main__.test'>
isinstance() 函数
这是 Python 中的另一个内置函数,用于确定对象是否是给定 class 的实例。
语法
isinstance(obj, class)
这个函数总是返回一个布尔值,如果对象确实属于给定的 class 则为 true,否则为 false。
示例
以下语句返回 True −
print (isinstance(10, int))
print (isinstance(2.56, float))
print (isinstance(2+3j, complex))
print (isinstance("Hello World", str))
它将产生以下 输出 −
True True True True
相反,这些语句打印 False。
print (isinstance([1,2,3], tuple))
print (isinstance({1:'one', 2:'two'}, set))
它将产生以下 输出 −
False False
您也可以对用户定义的 class 进行检查
class test: pass obj = test() print (isinstance(obj, test))
它将产生以下 输出 −
True
在 Python 中,class 本身也是对象。所有 class 都是 object class 的对象。这可以通过以下代码验证 −
class test: pass print (isinstance(int, object)) print (isinstance(str, object)) print (isinstance(test, object))
以上所有打印语句都会输出 True。
issubclass() 函数
这个函数检查一个 class 是否是另一个 class 的子类。它适用于 class,而不是它们的实例。
如前所述,所有 Python class 都继承自 object class。因此,以下打印语句的输出均为 True。
class test: pass print (issubclass(int, object)) print (issubclass(str, object)) print (issubclass(test, object))
它将产生以下 输出 −
True True True
callable() 函数
如果一个对象能够调用某个过程,则称其为可调用对象。Python 函数执行某个过程,因此是可调用对象。因此 callable(function) 返回 True。任何函数,包括内置函数、用户定义函数或方法,都是可调用对象。内置数据类型如 int、str 等的对象不是可调用对象。
示例
def test():
pass
print (callable("Hello"))
print (callable(abs))
print (callable(list.clear([1,2])))
print (callable(test))
字符串对象不是可调用对象。但 abs 是一个函数,是可调用对象。list 的 pop 方法是可调用对象,但 clear() 实际上是函数的调用,而不是函数对象,因此不是可调用对象。
它将产生以下输出 −
False True True False True
如果一个 class 实例具有 __call__() 方法,则它是可调用对象。在下面的示例中,test class 包含 __call__() 方法。因此,其对象可以像调用函数一样使用。因此,具有 __call__() 函数的 class 对象是可调用对象。
class test:
def __init__(self):
pass
def __call__(self):
print ("Hello")
obj = test()
obj()
print ("obj is callable?", callable(obj))
它将产生以下输出 −
Hello obj is callable? True
getattr() 函数
getattr() 内置函数用于获取对象的指定属性的值。
示例
class test:
def __init__(self):
self.name = "Manav"
obj = test()
print (getattr(obj, "name"))
它将产生以下输出 −
Manav
setattr() 函数
setattr() 内置函数为对象添加新属性并为其赋值。它也可以更改现有属性的值。
在下面的示例中,test class 的对象只有一个属性 − 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)
它将产生以下输出 −
Madhav 20
hasattr() 函数
这个内置函数如果对象参数具有指定的属性,则返回 True,否则返回 False。我们使用相同的 test class 来检查它是否具有某个属性。
class test:
def __init__(self):
self.name = "Manav"
obj = test()
print (hasattr(obj, "age"))
print (hasattr(obj, "name"))
它将产生以下输出 −
False True
dir() 函数
如果这个内置函数在没有参数的情况下被调用,它会返回当前作用域中的名称。对于任何作为参数的对象,它会返回给定对象及其可达属性的属性列表。
对于 module object − 该函数返回 module 的属性。
对于 class object − 该函数返回其属性,以及其基类的属性(递归)。
对于任何其他对象 − 其属性、其 class 的属性,以及其 class 的基类属性(递归)。
示例
print ("dir(int):", dir(int))
它将产生以下输出 −
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']
示例
print ("dir(dict):", dir(dict))
它将产生以下输出 −
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']
示例
class test:
def __init__(self):
self.name = "Manav"
obj = test()
print ("dir(obj):", dir(obj))
它将产生以下输出 −
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']