This article describes how to dynamically obtain the attributes and methods of objects in Python and run and use them, for more information, see the following example.
# 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 a class or instance. sayHi accesses print self. name, 'says Hi! '# Access the field named name and use the instance. name access cat = Cat () # cat is the Cat class instance object print Cat. sayHi # when using the class name to access the instance method, the method is unbound (unbound) print cat. sayHi # when using 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.
Cat = Cat ('Kitty ') print cat. name # access instance attributes cat. sayHi () # Call the instance method print dir (cat) # obtain the instance attribute name and return if hasattr (cat, 'name') in the form of a list '): # check whether the instance has this property setattr (cat, 'name', 'Tiger ') # same as:. name = 'tider' print getattr (cat, 'name') # same as: print. 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 __: 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 name-attribute dictionary available in the module, that is, the object that can be accessed using the module name. attribute name.
_ File __: contains the file path of the module. Note that the built-in module does not have this attribute. An exception is thrown when you access it!
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 During definition.
* _ Dict __: contains the attribute dictionary available in the class, that is, the object that can be accessed using the class name. 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 __: indicates the tuples of the parent class object, but does not include other classes on the upper layer of the inheritance tree, such as the parent class of the parent class.
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.
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 document.
_ Name __: The name used to define a function or method.
_ 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, the value is None.
* _ Module __: name of the module where the function or method is located.
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 __: name of the function when defining the function. you can also use the attribute name func_name.
* _ Module __: contains the module name defined by the function. Also, note that the module name is not the module object.
* _ Dict __: 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 values are always dependent on the backend parameters, the dictionary format can also correspond to the parameters.
Func_code: this attribute points to the code object corresponding to the function. the code object defines some other special attributes, which will be described below.
Func_globals: this attribute points to the current global namespace instead of the global namespace when defining the function. it is of little use and is read-only.
* 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:
# Coding: UTF-8 def foo (): n = 1 def bar (): print n # reference non-global external variable n, construct a closure n = 2 return bar closure = foo () print closure. func_closure # use dir () to know that the cell object has a cell_contents attribute and can obtain the print closure value. 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 attribute 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 this method, or the class of the instance that actually calls this method. Note that it is not the class where the method definition is located, if there is an inheritance relationship.
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.
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: total number of common parameters, excluding the * parameter and ** parameter.
Co_names: tuples of all parameter names (including * parameter and ** parameter) and local variable names.
Co_varnames: the tuples of all local variable names.
Co_filename: name of the source code.
Co_flags: this is a numerical value. each binary bit contains specific information. Note 0b100 (0x4) and 0b1000 (0x8). if co_flags & 0b100! = 0 indicates that the * args parameter is used. if co_flags & 0b1000! = 0. The ** kwargs parameter is used. In addition, if co_flags & 0b100000 (0 × 20 )! = 0 indicates that this is a generator function ).
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: used in the current stack frame 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 .......
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.
Def p (x, y): try: return x/y Records T: tb = sys. exc_info () [2] # return (exc_type, exc_value, traceback) print tb. tb_lineno # "return x/y" row number 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 *().
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.
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.
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.
print inspect.getmro(Cat) #(
,
) print Cat.__mro__ #(
,
)