A tutorial on dynamically fetching objects ' properties and methods in Python _python

Source: Internet
Author: User
Tags closure function definition generator inheritance instance method numeric value reflection in python

First, take a look at the objects and concepts that might be used in this article.

 #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, using a class or instance. Sayhi Access the
 print self.name, ' says hi! ' # access the field named name, use instance. Name Access
 
 cat = Cat () # cat is an instance object of the Cat class C10/>print Cat.sayhi # When using a class name to access an instance method, the method is unbound (unbound)
 Print Cat.sayhi # When the instance method is accessed using an instance, the method is bound (bound)

Sometimes we encounter the need to execute a method of an object, or to assign a value to a field of an object, and the method name or field name is not determined when coding code, and it needs to be entered in the form of a string passed by the parameter. To give a specific example: when we need to implement a generic dbm framework, we may need to assign values to the fields of the data object, but we cannot predict what fields the data objects used in the framework are, in other words, we need some mechanism to access the unknown properties when we write the framework.

This mechanism is called reflection (which in turn lets the object tell us what he is), or introspection (let the object tell us what he is, OK, I admit I made it up in parentheses--#), which is used to get information about an unknown object at run time. Reflection is a very frightening noun, sounding inscrutable, reflected in the general programming language is slightly more complex than other concepts, generally speaking as an advanced topic, but in Python reflection is very simple, with almost no sense of difference with other code, Functions and methods obtained using reflection can be called directly with parentheses as usual, and the instance can be constructed directly after the class has been obtained, but the obtained field cannot be directly assigned because it is actually another reference to the same place, and the assignment can only change the current reference.
1. Accessing the properties of an object

The following is a list of built-in methods that you can use to check or access the properties of an object. These methods can be used for arbitrary objects and not just cat instance objects in the example; everything in Python is an object.

 Cat = Cat (' Kitty ')
 
 print Cat.name # Access Instance Property
 Cat.sayhi () # Invoke instance method
 
 print dir (Cat) # Gets the property name of the instance, returns the
 if Hasa in a list form TTR (cat, ' name '): # Check to see if 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 returns a list that contains most of the property names for obj (there are special attributes that are not included). The default value for obj is the current module object.
hasattr (obj, attr):
This method is used to check if obj has a property named attr value, and returns a Boolean value.
getattr (obj, attr):
Calling this method returns the value of the property named attr value in obj, for example, if attr is ' bar ', returns Obj.bar.
setattr (obj, attr, val):
call this method to assign a value to Val for the property named attr for obj. For example, if attr is ' bar ', it is equivalent to Obj.bar = val.

2. Accessing the object's metadata

When you use Dir () on an object you construct, you may find that many of the attributes in the list are not defined by you. These properties generally hold the metadata of the object, such as the __name__ property of the class that holds the class name. Most of these properties can be modified, but changing them is not very significant; modifying some of these properties, such as Function.func_code, can also lead to problems that are difficult to discover, so change the name to something else, and do not modify the other attributes without understanding the consequences.

Next, you list some special properties for a particular object. In addition, the Python documentation mentions that some of the properties may not always be available, and the following will be marked with a red asterisk *, before you can use the interpreter to confirm it.
2.0. Preparation: Determining the type of object

All of the Python built-in types are defined in the types module, with the built-in method Isinstance () to determine the specific type of object.

Isinstance (object, ClassInfo):
Check if object is a type enumerated in ClassInfo and return a Boolean value. ClassInfo can be a specific type, or it can be a tuple or list of multiple types.

The types module only defines the type, and the inspect module encapsulates a number of methods for checking the type, which is easier than using the types module directly, so there is no more introduction to types, and if necessary you can view the documentation for the types module directly. The inspect module is described in section 3rd of this article.
2.1. Modules (module)

__DOC__: Document String. If the module does not have a document, this value is none.
*__NAME__: Always be the name of the module at the time of definition, even if you use import. As an alias for it, or an assignment to another variable name.
*__dict__: A Dictionary of property names-attributes available in the module, which is the object that can be accessed using the module name.
__FILE__: Contains the file path for the module. It should be noted that the built-in module does not have this attribute, access it will throw an exception!

 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 ', <function fnmatchcase= "" at= "" 0xb73deb54= "" >) </function>

2.2. Classes (Class)

__DOC__: Document String. If the class does not have a document, this value is none.
*__NAME__: Always the name of the class at the time of the definition.
*__dict__: A Dictionary of property names-attributes that are available in the class, which is the object that can be accessed using the class name. Property name.
__MODULE__: The name of the module that contains the definition of the class, and note that the module name, rather than the module object, is the string form.
*__bases__: The tuple of a direct parent class object, but does not contain other classes that are higher up 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__ # (< Type? object?= "",)
 print cat.__dict__ # {' __module__ ': ' __main__ ', ...} </type>

2.3. Example (instance)

An instance is an object after a class is instantiated.

*__DICT__: Contains the available property names-attribute dictionaries.
*__CLASS__: The class object for this instance. True for class cat,cat.__class__ = = Cat.

 Print cat.__dict__
 print cat.__class__
 print cat.__class__ = = Cat # True

2.4. Built-in functions and methods (built-in functions and methods)

The built-in (built-in) module, by definition, refers to modules that are written in C, which can be viewed through the Sys module's builtin_module_names field to see which modules are built in. The functions and methods in these modules can use fewer properties, but generally do not need to view their information in code.

__DOC__: A document for a function or method.
__NAME__: The name of a function or method definition.
__self__: Only the method is available, if it is bound (bound), the class that calls the method (if it is a class method) or an instance (if it is an instance method) or none.
*__MODULE__: The name of the module where the function or method is located.

2.5. Functions (function)

This refers specifically to a function that is not built in. Note that using DEF in a class defines a method, and methods and functions have similar behavior, but they are different concepts.

__DOC__: A document for a function, or it can be func_doc with a property name.
__NAME__: The name of a function when it is defined, or it can be func_name with a property name.
*__MODULE__: The name of the module that contains the function definition, and also note that the module name is not the module object.
*__DICT__: The available properties of the function, or the property name Func_dict.
Don't forget that a function is also an object, and you can use a function. Property name Access Property (if the property does not exist when the assignment is added), or use the built-in function has/get/setattr () access. However, it does not make sense to hold attributes in a function.
Func_defaults: This property holds the parameter default value tuple for the function, because the default value is always dependent on the parameter, so the form that does not use the dictionary can also correspond to the parameter.
Func_code: This attribute points to a code object for the function, and some other special attributes are defined in the code object, which are described in the following article.
Func_globals: This attribute points to the current global namespace instead of the global namespace when the function is defined, and is not very useful and is read-only.
*func_closure: This property is valid only if the function is a closure, point to a tuple of the variable cell that holds the referenced external function, and always none if the function is not an intrinsic function. This property is also read-only.

The following code shows the 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
 
 Clos ure = foo ()
 print closure.func_closure
 # use DIR () to learn that the Cell object has a Cell_contents property to get the value of
 print closure.func_ Closure[0].cell_contents # 2

As you can see from this example, it is a good idea to encounter an unknown object using Dir ():
2.6. Methods (method)

The method is not a function, but it can be understood to add a shell outside the function, and after you get the actual function in the method, you can use the attributes of section 2.5.

__DOC__: Same as function.
__NAME__: Same as function.
*__MODULE__: Same as function.
Im_func: Use this property to get a reference to the actual function object in the method. In addition, if it is more than 2.6 versions, you can also use the property name __func__.
Im_self: If it is bound (bound), it points to the class that called the method (if it is a class method) or to an instance (if it is an instance method) or none. If the version is more than 2.6, you can also use the property name __self__.
Im_class: The class that actually calls the method, or the instance that actually calls the method. Note the class that is not the definition of the method, 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 example method is discussed here, and there are two special methods, namely the class method (Classmethod) and the static method (Staticmethod). Class method is still a method, but because it needs to be invoked with the class name, the static method can be viewed as a function in the namespace of the class (a function that needs to be called using the class name), it can only use the properties of the function, and cannot use the properties of the method.
2.7. Generator (generator)

The builder is the object returned by calling a generator function (generator function), which is used more than the iteration of the collection object.

__ITER__: Just an iterative marker.
Gi_code: Generator corresponding to the code object.
Gi_frame: The frame object that the generator corresponds to.
Gi_running: Whether the generator function is executing. The generator function is in the frozen state after yield, before the next line of code that executes yield, at which point the value of this property is 0.
Next|close|send|throw: This is a few callable methods that do not contain metadata information and how to use documents related to viewing the builder.

 Def Gen (): For
 N in xrange (5):
 yield n
 g = gen ()
 print G # <generator object Gen at 0x...>
 print G.gi_code # <code Object Gen at 0x...>
 print G.gi_frame # <frame object at 0x...>
 print g.gi_running # 0
 Print g.next () # 0
 Print G.next () # 1
 for N in G:
 print N, # 2 3 4

The next discussion is a few of the built-in object types that are not commonly used. These types should be rarely contacted in the normal coding process unless you are implementing an interpreter or development environment yourself. So there are only a few attributes listed here, and if you need a complete property sheet or want to learn more, you can view the reference documentation listed at the end of the article.
2.8. Code block

The code block can be compiled from the class source code, the function source code, or a simple statement code. Here we only consider the case when it refers to a function, and we mentioned in section 2.5 that you can get it using the Func_code property of the function. The properties of the code are all read-only.

Co_argcount: Total number of normal parameters, excluding * parameters and * * parameters.
Co_names: all parameter names (including * parameters and * * parameters) and tuples of local variable names.
Co_varnames: The tuple of all local variable names.
Co_filename: The name of the file where the source code resides.
Co_flags: This is a numeric value, and each bits contains specific information. More attention is paid to 0b100 (0x4) and 0b1000 (0x8), if Co_flags & 0b100!= 0, the *args parameter is used, and if Co_flags & 0b1000!= 0, the **kwargs parameter is used. Also, if Co_flags & 0b100000 (0x20)!= 0, this is a generator function (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 (frame)

A stack frame represents a frame in a function call stack when the program is running. The function has no attributes to get it, because it is generated when the function is called, and the generator is returned by the function call, so the attribute points to the stack frame. To get the stack frame associated with a function, you must get it when the function is called and the function is not returned. You can get the current stack frame using the _getframe () function of the Sys module, or the Currentframe () function of the inspect module. The attributes listed here are all read-only.

F_back: The previous frame of the call stack.
F_code: The code object corresponding to the stack frame.
F_locals: The same as the built-in function locals () when used in the current stack frame, but you can get the other frames and then use this property to get the locals () of that frame.
F_globals: The same as the built-in function globals () when used in the current stack frame, 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 # <frame obj ECT at 0x...> return
 x+y
 Add (2)

2.10. Tracing (Traceback)

Tracing is an object that is used for backtracking when an exception occurs, as opposed to a stack frame. is built only when the exception is not caught, and it is thrown to the outer stack frame when the exception is not captured, so you need to use a try to see the object. You can get it using the Exc_info () function of the SYS module, which returns a tuple, which is the exception type, the exception object, and the trace. The properties of the Traceback are all read-only.

Tb_next: The next tracking object.
Tb_frame: current trace corresponding stack frame.
Tb_lineno: The line number of the current trace.

 def div (x, y):
 try: Return
 x/y
 except:
 TB = Sys.exc_info () [2] # return (Exc_type, Exc_value, Traceback) C5/>print TB
 Print Tb.tb_lineno # "return x/y" line number
 div (1, 0)

3. Using the Inspect module

The inspect module provides a series of functions to help with introspection. Here are just a few of the more commonly used functions to see the documentation of the inspect module for full function data.
3.1. Check object type

Is{module|class|function|method|builtin} (obj):
checks whether the object is a module, class, function, method, built-in function, or method.
isroutine (obj):
used to check whether an object is a function, method, built-in function, or method, and so on callable types. This method is more convenient than multiple is* (), but its implementation is still using multiple is* ().

 im = Cat.sayhi
 if Inspect.isroutine (IM):
 im ()


This method returns false for the class instance that implements the __call__. Use Isinstance (obj, collections) If the goal is true if you want to call it directly. Callable) This form. I don't know why callable in the collections module, sorry! I guess it's probably because the collections module contains a lot of 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 by Dir (), in the form of [(name, Value), ...]. In addition, predicate is a reference to a method that, if specified, should accept value as a parameter and return a Boolean value, and if False, the corresponding property will not be returned. Use is* as the second parameter to filter out properties of the specified type.
    GetModule (object):
    Are you sorry to return only a string for the __module__ property in section 2nd? This method will certainly satisfy you, it returns the Module object where the object's definition resides.
    Get{file|sourcefile} (object):
    Get the file name of the module where the object is defined | source code file name (none is returned if not). TypeError exceptions are thrown on built-in objects (built-in modules, classes, functions, methods).
     Get{source|sourcelines} (object):
    Get the source code for the definition of object. Returns as a String | string list. IOError exceptions are thrown when code is not accessible. Can only be used for Module/class/function/method/code/frame/traceack objects.
    Getargspec (func):  
    is used only for methods, gets arguments for method declarations, returns tuples, respectively ( List of normal parameter names, * parameter names, * * parameter names, default value tuples. If there is no value, it will be an empty list and 3 none. In the case of version 2.6, a named tuple (Named Tuple) is returned, which means that an attribute name can be used to access elements in the tuple in addition to the index.  

 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):
for the stack frame only, get the parameter value of the function call saved in the stack frame, and return the tuple, respectively (a list of normal parameter names, * parameter names, * * parameter names, locals () of the frames). In the case of version 2.6, a named tuple (Named Tuple) is returned, which means that an attribute name can be used to access elements in the tuple in addition to the index.

 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 a dictionary of the values corresponding to each parameter when the method is called using args and Kwds. This method is only available in version 2.7.
Getmro (CLS):
returns a type tuple that finds the class attributes in the order in which they are set. If it is a new class, it is the same as the cls.__mro__ result. But the legacy class does not __mro__ this attribute, and using this property directly reports an exception, so this method has its value.

 Print Inspect.getmro (Cat)
 # (<class ' __main__.) Cat ', <type ' object ' > '
 print cat.__mro__
 # (<class ' __main__. Cat ", <type ' object ' >)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.