This article mainly introduces the introspection (reflection) in Python. This article explains how to access object attributes, access object metadata, and determine object types, for more information about the objects and related concepts, see an example.
The Code is as follows:
# Coding:
UTF-8
Import sys
#
Module. sys points to this module object.
Import inspect
Def foo ():
Pass #
Function. foo points to this function object.
Class Cat (object ):
#
Class, Cat points to this class Object
Def _ init _ (self,
Name = 'Kitty '):
Self. name
= Name
Def sayHi (self ):
#
Instance method. sayHi points to this method object and uses class or instance. sayHi for access.
Print self. name,
'Says
Hi! '#
Access the field named name by using instance. name
Cat
= Cat ()
#
Cat is an instance object of the Cat class.
Print Cat. sayHi
#
When using the class name to access the instance method, the method is unbound (unbound)
Print cat. sayHi
#
When you use the instance access method, the method is bound (bound)
Sometimes we need to execute a method of the object or assign a value to a field of the object. The method name or field name cannot be determined when coding the code, you must input a string using parameters. For example, to implement a common DBM framework, you may need to assign values to the fields of the data object, however, we cannot predict the fields of data objects that use this framework. In other words, when writing a framework, we need to access unknown attributes through some mechanism.
This mechanism is called reflection (which in turn allows an object to tell us what it is) or introspection (letting the object tell us what it is, okay, I admit that I am lying in the brackets---#), used to get information about unknown objects at runtime. Reflection is a very scary term. It sounds uncertain. reflection in a general programming language is a little more complex than other concepts. Generally, reflection is a high-level topic; however, reflection in Python is very simple, and it hardly feels different from other code. The functions and methods obtained by reflection can be directly called with parentheses as usual, the instance can be constructed directly after the class is obtained. However, the obtained field cannot be assigned a value directly, because another reference pointing to the same place is obtained, and the value assignment can only change the current reference.
1. Access Object Attributes
The following lists several built-in methods that can be used to check or access the attributes of an object. These methods can be used for any object, not just the Cat instance object in the example; everything in Python is an object.
The Code is as follows:
Cat
= Cat ('Kitty ')
Print cat. name
#
Access instance attributes
Cat. sayHi ()
#
Call instance method
Print dir (cat)
#
Obtains the attribute name of an instance and returns it as a list.
If hasattr (cat,
'Name '):
#
Check whether the instance has this attribute.
Setattr (cat,
'Name ',
'Tiger ')
#
Same as: a. name = 'tiger'
Print getattr (cat,
'Name ')
#
Same as: print a. name
Getattr (cat,
'Sayhi ')()
#
Same as: cat. sayHi ()
Dir ([obj]):
Calling this method will return a list containing most of the obj attribute names (some special attributes are not included ). The default value of obj is the current module object.
Hasattr (obj, attr ):
This method is used to check whether obj has an attribute named attr and returns a Boolean value.
Getattr (obj, attr ):
Calling this method will return the attribute value named attr in obj. For example, if attr is 'bar', obj. bar is returned.
Setattr (obj, attr, val ):
To call this method, the attribute named attr of obj is assigned val. For example, if attr is 'bar', it is equivalent to obj. bar = val.
2. Access object metadata
When you use dir () for a constructed object, you may find that many attributes in the list are not defined by you. These attributes generally Save the metadata of the object. For example, the _ name _ attribute of the class stores the class name. Most of these attributes can be modified, but they do not make much sense. modify some of these attributes, such as function. func_code can also cause problems that are difficult to find, so you can just change the name or something. Do not modify other attributes without knowing the consequences.
Next, we will list some special attributes of a specific object. In addition, some attributes mentioned in the Python document may not always be provided. The red asterisk * will be used in the following sections. You can open the interpreter to check before using it.
2.0. Preparation: determine the object type
All Python built-in types are defined in the types module. The specific object types can be determined by using the built-in method isinstance.
Isinstance (object, classinfo ):
Check whether the object is the type listed in classinfo and return a Boolean value. Classinfo can be a specific type, or multiple types of tuples or lists.
The types module only defines types, while the inspect module encapsulates many methods for checking types, which is easier than directly using the types module. Therefore, we will not provide more information about types here, if necessary, you can directly view the document description of the types module. The inspect module is described in Section 3rd.
2.1. module)
_ Doc __:Document string. If the module does not have a document, the value is None.
* _ Name __:It is always the module name during definition, even if you use import... as to get an alias for it, or assign a value to another variable name.
* _ Dict __:Contains the attribute dictionary available in the module, that is, the object that can be accessed using the module name and attribute name.
_ File __:Contains the file path of this module. Note that the built-in module does not have this attribute. An exception is thrown when you access it!
The Code is as follows:
Import fnmatch
As m
Print m. _ doc _. splitlines () [0]
#
Filename matching with shell patterns.
Print m. _ name __
#
Fnmatch
Print m. _ file __
#
/Usr/lib/python2.6/fnmatch. pyc
Print m. _ dict _. items () [0]
#
('Fnmatchcase ', )
2.2. class)
_ Doc __:Document string. If the class does not have a document, the value is None.
* _ Name __:Always the class name for definition.
* _ Dict __:Contains the attribute dictionary available in the class, that is, the object that can be accessed using the class name and attribute name.
_ Module __:The module name that contains the definition of this class. Note that it is a module name in the string format, not a module object.
* _ Bases __:The tuples of the parent class objects directly, but do not include other classes on the upper layer of the inheritance tree, such as the parent class of the parent class.
The Code is as follows:
Print Cat. _ doc __
#
None
Print Cat. _ name __
#
Cat
Print Cat. _ module __
#
_ Main __
Print Cat. _ bases __
#
( ,)
Print Cat. _ dict __
#
{'_ Module _': '_ main __',...}
2.3. instance)
An instance is an object after the class is instantiated.
* _ Dict __: contains the available attribute name-attribute dictionary.
* _ Class __: class Object of the instance. For Cat classes, cat. _ class _ = Cat is True.
The Code is as follows:
Print cat. _ dict __
Print cat. _ class __
Print cat. _ class __
= Cat
#
True
2.4. built-in functions and methods)
According to the definition, the built-in (built-in) module refers to the module written in C. You can check which modules are built in through the builtin_module_names field of the sys module. The functions and methods in these modules have fewer attributes, but they generally do not need to be viewed in the code.
_ Doc __:Function or method documentation.
_ Name __:The name when the function or method is defined.
_ Self __:Only the method is available. If it is bound (bound), it points to the class (if it is a class method) or instance (if it is an instance method) that calls this method, otherwise it is None.
* _ Module __:The module name of the function or method.
2.5. Functions)
This is a non-built-in function. Note that def is used in classes to define methods. Methods and functions have similar behaviors, but they are different concepts.
_ Doc __:Function documentation. You can also use the attribute name func_doc.
_ Name __:The function name when the function is defined. You can also use the attribute name func_name.
* _ Module __:The name of the module that contains the function definition. Also, note that the module name is not the module object.
* _ Dict __:The available attribute of the function. You can also use the attribute name func_dict.
Do not forget that the function is also an object. You can use the function. attribute name to access the attribute (if the attribute does not exist, a new one will be added), or use the built-in function has/get/setattr () for access. However, saving attributes in a function is of little significance.
Func_defaults:This attribute stores the default value tuples of the function parameters. Because the default value is always a back-to-back parameter, it can correspond to parameters without using dictionaries.
Func_code:This attribute points to the code object corresponding to the function. The code object defines some other special attributes, which will be further described below.
Func_globals:This attribute points to the global namespace when defining the function.
* Func_closure:This attribute is valid only when the function is a closure and points to the cell variable that stores the referenced external function. If the function is not an internal function, it is always None. This attribute is also read-only.
The following code demonstrates func_closure:
The Code is as follows:
# Coding:
UTF-8
Def foo ():
N
= 1
Def bar ():
Print n
#
Reference non-global external variable n to construct a closure
N
= 2
Return bar
Closure
= Foo ()
Print closure. func_closure
#
You can use dir () to know that the cell object has a cell_contents attribute to obtain the value.
Print closure. func_closure [0]. cell_contents
#
2
In this example, we can see that using dir () for unknown objects is a good idea :)
2.6. method)
Although the method is not a function, it can be understood that a shell is added to the function. After obtaining the actual function in the method, you can use the attribute in section 2.5.
_ Doc __:Same as the function.
_ Name __:Same as the function.
* _ Module __:Same as the function.
Im_func:You can use this property to obtain the reference of the actual function object in the method. In addition, for Versions later than 2.6, you can also use the attribute name _ func __.
Im_self:If it is bound (bound), it points to the class (if it is a class method) or instance (if it is an instance method) that calls this method, otherwise it is None. For Versions later than 2.6, you can also use the attribute name _ self __.
Im_class:The class that actually calls the method, or the class of the instance that actually calls the method. Note that it is not the class where the method definition is located, if there is an inheritance relationship.
The Code is as follows:
Im
= Cat. sayHi
Print im. im_func
Print im. im_self
#
Cat
Print im. im_class
#
Cat
The general instance method is discussed here. There are two special methods, classmethod and staticmethod ). Class method or method, but it is always bound because it needs to be called by class name; the static method can be regarded as a function in the namespace of the class (a function called by the class name is required). It can only use the attributes of the function, but cannot use the attributes of the method.
2.7. generator)
A generator is an object returned by calling a generator function. It is mostly used for the iteration of a collection object.
_ Iter __: it is just an iterative tag.
Gi_code: the code object corresponding to the generator.
Gi_frame: The frame object corresponding to the generator.
Gi_running: whether the generator function is being executed. The generator function is in the frozen state after yield and before the next line of yield code is executed. The value of this attribute is 0.
Next | close | send | throw: This is a few callable methods that do not contain metadata. You can view the relevant documentation of the generator for how to use it.
The Code is as follows:
Def gen ():
For n
In xrange (5 ):
Yield n
G
= Gen ()
Print g
#
Print g. gi_code
#
print g.gi_frame
#
print g.gi_running
#
0
print g.next()
#
0
print g.next()
#
1
for n
in g:
print n,
#
2 3 4
Next we will discuss several built-in object types that are not frequently used. These types should be rarely used during normal encoding, unless you are implementing an interpreter or development environment on your own. Therefore, only some attributes are listed here. If you need a complete Attribute Table or want to learn more, you can view the reference documents listed at the end of this article.
2.8. code Block)
The code block can be compiled by the class source code, function source code, or a simple statement code. Here, we only consider how it refers to a function. We mentioned in section 2.5 that it can be obtained using the func_code attribute of the function. All the code attributes are read-only.
Co_argcount:The total number of common parameters, excluding * parameters and ** parameters.
Co_names:Tuples of all parameter names (including * And ** parameters) and local variable names.
Co_varnames:The tuples of all local variable names.
Co_filename:The file name of the source code.
Co_flags:This is a value. Each binary BIT contains specific information. We are concerned with 0b100 (0x4) and 0b1000 (0x8). If co_flags &0b100! = 0The * args parameter is used. If co_flags & 0b1000! = 0. The ** kwargs parameter is used. In addition, if co_flags &0b100000 (0x20 )! = 0It indicates that this is a generator function ).
The Code is as follows:
co
= cat.sayHi.func_code
print co.co_argcount
#
1
print co.co_names
#
('name',)
print co.co_varnames
#
('self',)
print co.co_flags
& 0b100 #
0
2.9. stack frame)
Stack frame indicates a frame in the function call stack when the program is running. A function has no attribute to obtain it, because it is generated only when the function is called, and the generator is returned by the function call. Therefore, the attribute points to the stack frame. To obtain stack frames related to a function, you must obtain them when calling this function and the function has not yet been returned. You can use the _ getframe () function of the sys module or the currentframe () function of the inspect module to obtain the current stack frame. All the attributes listed here are read-only.
F_back:The previous frame of the call stack.
F_code:The code object corresponding to the stack frame.
F_locals:When used in the current stack frame, it is the same as the built-in function locals (), but you can get other Frames first and then use this attribute to get the locals () of that frame ().
F_globals:The current stack frame is the same as the built-in function globals (), but you can get other Frames first .......
The Code is as follows:
def add(x,
y=1):
f
= inspect.currentframe()
print f.f_locals
#
same as locals()
print f.f_back
#
return x+y
add(2)
2.10. Trace (traceback)
Tracing is an object used for backtracking when an exception occurs, which is opposite to stack frames. This object is constructed only when an exception occurs, but is always thrown to the outer stack frame when the exception is not captured. Therefore, you need to use try to see this object. You can use the exc_info () function of the sys module to obtain it. This function returns a tuples with the exception type, exception object, and tracing elements. All traceback attributes are read-only.
Tb_next:The next tracing object.
Tb_frame:Stack frame corresponding to the current tracing.
Tb_lineno:The row number of the current trail.
The Code is as follows:
Def p (x,
Y ):
Try:
Return x/y
Except t:
Tb
= Sys. exc_info () [2]
#
Return (exc_type, exc_value, traceback)
Print tb
Print tb. tb_lineno
#
The row number of "return x/y"
P (1,
0)
3. Use the inspect Module
The inspect module provides a series of functions to help with introspection. The following lists some commonly used functions. For more information about the functions, see the inspect module documentation.
3.1. Check the object type
Is {module | class | function | method | builtin} (obj ):
Check whether the object is a module, class, function, method, built-in function or method.
Isroutine (obj ):
It is used to check whether an object is a function, method, built-in function, or method call type. This method is more convenient than multiple is * (), but its implementation still uses multiple is *().
The Code is as follows:
im
= cat.sayHi
if inspect.isroutine(im):
im()
For a class instance that implements _ call _, this method returns False. If it is required to be True if it can be called directly, use the isinstance (obj, collections. Callable) format. I don't know why Callable will be in the collections module. Sorry! I guess it is because the collections module contains many other ABC (Abstract Base Class :)
3.2. Get Object Information
getmembers(object[, predicate]):
This method is an extended version of dir (). It returns the attributes corresponding to the name found in dir (), such as [(name, value),...]. In addition, predicate is a reference to a method. If it is specified, value should be accepted as a parameter and a Boolean value should be returned. If it is False, the corresponding attribute will not be returned. Use is * as the second parameter to filter out attributes of the specified type.
Getmodule (object ):
Is the _ module _ attribute in section 2nd still returning only strings, but sorry? This method can satisfy your needs. It returns the module object of the object definition.
Get {file | sourcefile} (object ):
Get the file name of the module where the object definition is located | source code file name (if not, None is returned ). A TypeError exception is thrown when it is used on built-in objects (built-in modules, classes, functions, and methods.
Get {source | sourcelines} (object ):
Obtains the source code defined in the object and returns it with a string | string list. An IOError occurs when the Code cannot be accessed. It can only be used for module/class/function/method/code/frame/traceack objects.
Getargspec (func ):
It is only used for methods to obtain the parameters declared by the method. The returned tuples are (list of common parameter names, * parameter names, ** parameter names, and default value tuples ). If there is no value, it will be an empty list and three None. If the version is 2.6 or later, a Named Tuple is returned, that is, in addition to the index, attribute names can also be used to access the elements in the tuples.
The Code is as follows:
def add(x,
y=1,
*z):
return x
+ y
+ sum(z)
print inspect.getargspec(add)
#ArgSpec(args=['x',
'y'], varargs='z', keywords=None, defaults=(1,))
Getargvalues (frame ):
Used only for Stack frames. Get the parameter values of the function call stored in the stack frames. The returned tuples are (list of common parameter names, * parameter names, ** parameter names, the locals () of the frame ()). If the version is 2.6 or later, a Named Tuple is returned, that is, in addition to the index, attribute names can also be used to access the elements in the tuples.
The Code is as follows:
def add(x,
y=1,
*z):
print inspect.getargvalues(inspect.currentframe())
return x
+ y
+ sum(z)
add(2)
#ArgInfo(args=['x',
'y'], varargs='z', keywords=None, locals={'y': 1, 'x': 2, 'z': ()})
getcallargs(func[, *args][, **kwds]):
Returns the dictionary of values corresponding to each parameter when args and kwds call this method. This method is available only in version 2.7.
getmro(cls):
A type tuples are returned, which are sorted by class attributes. For new classes, the results are the same as those of cls. _ mro. However, the old class does not have the _ mro _ attribute. Using this attribute directly will report an exception, so this method still has its value.
The Code is as follows:
print inspect.getmro(Cat)
#( '__main__.Cat'>, )
print Cat.__mro__
#( '__main__.Cat'>, )
class Dog:
pass
print inspect.getmro(Dog)
#( __main__.Dog at 0x...>,)
print Dog.__mro__
#
AttributeError
currentframe():
Returns the current stack frame object.
For details about other frame and traceback functions, refer to the inspect module documentation, which is rarely used.