在面向对象编程中,反射指的是提取有关任何正在使用对象的信息的能力。你可以了解对象的类型,它是其他类的子类吗,它的属性是什么等等。Python 的标准库中有几个函数可以反映对象的不同属性。反射有时也称为内省。
以下是 Python 中的反射函数列表:
type()
函数
我们多次使用过这个函数。它告诉你一个对象属于哪个类。
示例
下面的语句打印不同内置数据类型对象各自的类:
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 test:
pass
obj = test()
print(type(obj))
它将产生以下输出:
<class '__main__.test'>
isinstance()
函数
这是 Python 中的另一个内置函数,确定一个对象是否是给定类的一个实例。
语法
isinstance(obj, class)
这个函数总是返回一个布尔值,在对象确实属于给定类时返回真,在不属于时返回假。
示例
下面的语句返回 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 test:
pass
obj = test()
print(isinstance(obj, test))
它将产生以下输出:
True
在 Python 中,甚至类也是对象。所有类都是 object
类的对象。可以通过以下代码验证:
class test:
pass
print(isinstance(int, object))
print(isinstance(str, object))
print(isinstance(test, object))
以上所有打印语句打印 True
。
issubclass()
函数
这个函数检查一个类是否是另一个类的子类。涉及的是类本身,而不是它们的实例。
如前所述,所有的 Python 类都是 object
类的子类。因此,下面打印语句的输出对于所有情况都是 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
是一个函数,是可调用的。列表的 pop
方法是可调用的,但 clear()
实际上是对函数的调用而不是函数对象,因此不是一个可调用的。
它将产生以下输出:
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))
它将产生以下输出:
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
类的对象只有一个属性 —— 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 test:
def __init__(self):
self.name = "Manav"
obj = test()
print(hasattr(obj, "age"))
print(hasattr(obj, "name"))
它将产生以下输出:
False
True
dir()
函数
如果这个内置函数没有参数,则返回当前作用域中的名称。对于任意对象作为参数,它返回给定对象的属性列表及其可到达的属性。
对于模块对象 —— 函数返回模块的属性。
对于类对象 —— 函数返回其属性,并递归返回其基类的属性。
对于其他任何对象 —— 其属性,其类的属性,并递归返回其类的基类的属性。
示例
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__', '__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']