Category:Python之路
Article From:https://www.cnblogs.com/strive-man/p/9123317.html

 

First, take an example to see the objects and related concepts that may be used in this article.

#coding:utf-8
import sys

def foo():pass

class Cat(object):
    def __init__(self, name='Kitty'):
        self.name = name

    def sayHi(self):
        print self.name, 'says Hi!'

cat = Cat()

print Cat.sayHi
print cat.sayHi

Sometimes we encounter such a requirement that we need to execute some method of the object or to assign a field to a field of the object, and the name of the method or field name is not determined when the code is coded, and it needs to be input by the form of a parameter passing the string. Let’s take a concrete example: when we need to implement a universal DBM frameworks may need to assign a value to the field of a data object, but we can’t predict what fields have a data object to use for the framework, in other words, we need to access the unknown properties by some mechanism when writing the framework.

This mechanism is called reflection (in turn let the object tell us what he is), or introspection (let the object tell us what he is, so I admit that I’m blind in parentheses) to get information about the unknown objects at run time. Reflection is a very frightening term. It sounds profound.In the general programming language, reflection is slightly more complex than other concepts, generally speaking as a senior topic; but in Python, reflection is very simple, and it can hardly feel different from other codes. The functions and methods obtained by reflection can be added to parentheses as usual.Directly invocation, after getting to the class, you can directly construct an instance; but the acquired field cannot be assigned directly because it is actually another reference to the same place, and the assignment can only change the current reference.

1. Attributes of access objects

Listed below are several built-in methods that can be used to check or access properties of objects. These methods can be applied to any object, not just the Cat instance object in the example.PythonEverything is the object.

#coding:utf-8
from a import *

cat = Cat('kitty')

print cat.name
cat.sayHi()    #Invoking an instance method

print dir(cat)

if hasattr(cat, 'name'): #Check if the instance has this property
    setattr(cat, 'name', 'tiger') #same as: a.name = 'tiger'
    print getattr(cat, 'name') #same as: print a.name

    
getattr(cat, 'sayHi')()

    dir([obj]):
    Calling this method returns a list containing the names of most of the obj attributes (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 if obj has an attribute named attr and returns a Boolean value.
    getattr(obj, attr): 
    Invoking this method returns the value of the attribute named attr value in obj, for example, if attr is’ bar ‘, then obj.bar is returned.
    setattr(obj, attr, val):
    Calling this method will assign an attribute of Val to the value of obj named attr. For example, if attr is’ bar ‘, it is equivalent to obj.bar = Val.

 

2. Metadata for access objects

When you use dir () for an object you construct, you may find that many attributes in the list are not defined by you. These attributes generally hold the metadata of an object, such as the class’s __name__ attribute, which preserves the class name. Most of these properties can be modified, but changing them is not meaningful.It’s very big; modifying some of these properties, such as function.func_code, can also cause problems that are difficult to find, so it’s good to change name, and other properties do not change without understanding the consequences.

Next, we list some special attributes of specific objects. In addition, some of the attributes mentioned in the Python document will not always be provided, and the red asterisk will be marked in the following. You can first open the interpreter before using it.

2.0. Preparation: determine the type of the object

In the types module, all the Python built-in types are defined, and the specific types of objects can be determined by the built-in method isinstance ().

  • isinstance(object, classinfo): 
    Check whether object is the type listed in classInfo and return Boolean value. ClassInfo can be a specific type, or can be multiple types of tuples or lists.

typesThe modules are only defined in the module, and the inspect module encapsulates many methods for checking types, which is easier than using the types module directly, so there is no more introduction to types, if there is a need to see the document description of the types module directly. The third section of this articleThe inspect module is introduced in this paper.

2.1. Module (module)

  • __doc__: Document string. If the module does not have a document, the value is None.
  • *__name__: It is always the module name at the time of definition; even if you use import… As to alias it, or assign it to another variable name.
  • *__dict__: Contains a dictionary of attribute names and properties available in modules; that is, objects that can be accessed using module names.
  • __file__: The file path of the module is included. It should be noted that the built-in module does not have this property, and it will throw exceptions when accessing it.
#coding:utf-8
import fnmatch as m

print m.__doc__.splitlines()[0]
print m.__name__
print m.__file__
print m.__dict__.items()[0]

__dict__ Returns the dictionary of attributes and method object name values, while dir is just a list of attributes and method names.

2.2. Class (class)

  • __doc__: Document string. If the class does not have a document, the value is None.
  • *__name__: All the time is the name of the class at the time of definition.
  • *__dict__: A dictionary containing attribute names and properties available in classes; that is, objects that can be accessed using class names and property names.
  • __module__: The module name that contains the class definition; it should be noted that the module name of the string is not the module object.
  • *__bases__: The tuple of the parent class object directly; however, it does not contain other classes of the upper tree of the inheritance tree, such as the parent class of the parent class.
#coding:utf-8
from a import *

print Cat.__doc__ #None CatClass has no doc
print Cat.__name__ #Cat
print Cat.__module__ # a If __main__ is executed in your own module
print Cat.__bases__ #(<type 'object'>,)
print Cat.__dict__ # A dictionary of the value of an attribute, method object name

2.3. An example (instance)

An instance refers to the object after the instantiation of a class.

  • *__dict__: It contains the available attribute name – attribute object dictionary.
  • *__class__: The class object of the instance. For class Cat, cat.__class__ = = Cat is True.
#coding:utf-8
from a import *

print cat.__dict__ #{'name': 'Kitty'} Only property, no way
print cat.__class__ #<class 'a.Cat'>
print cat.__class__ == Cat #True

 

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

By definition, the built – in (built-in) module is a module written with C, which can see which modules are built through the builtin_module_names field of the sys module. The functions and methods used in these modules can be used less.There is no need to view their information in code.

  • __doc__: A document of a function or method.
  • __name__: The name of a function or method when it is defined.
  • __self__: The only method is available, and if it is bound (bound), it points to the class that calls the method (if it is a class method) or an instance (if it is an instance method), otherwise it is None.
  • *__module__: The name of the module in which the function or method is located.

2.5. Function (function)

This refers to the non – built function. Note that using def in classes is defined as methods. Although methods and functions have similar behaviors, they are different concepts.

  • __doc__: The document of function; in addition, you can use the attribute name func_doc.
  • __name__: The function name of function definition; in addition, the attribute name func_name can also be used.
  • *__module__: The module name that contains the function definition; similarly, it is the module name instead of the module object.
  • *__dict__: The properties of the function can be used; in addition, the attribute name func_dict can also be used. Do not forget that the function is an object, you can use a function. A property name is used to access an attribute (when a value is not added if the attribute does not exist), or access by using the built-in function has/get/setattr (). NoToo, the meaning of preserving attributes in a function is not significant.
  • func_defaults: This property preserves the parameter default tuple of the function; because the default values always depend on the later parameters, it is also possible to correspond to the parameters without the use of a dictionary.
  • func_code: This attribute points to a code object corresponding to the function, and some other special attributes are defined in the code object.
  • func_globals: This attribute points to the current global namespace rather than the global namespace when it is defined. It is not useful and read-only.
  • *func_closure: This property is valid only when the function is a closure, pointing to a tuple of the variable cell that holds the external function that is referenced, and this property is also read-only. (through func_closure you can see the required report)
#coding:utf-8
def foo():
    name = 'zhangsan'
    age = 11

    def bar():
        print name, age

    return bar

closure = foo()

print closure.func_closure 
# (<cell at 0x7f2fa7d36558: int object at 0x19f7b78>, <cell at 0x7f2fa7d36590: str object at 0x7f2fa7d37450>)

for cell in closure.func_closure:
    print cell.cell_contents
    # zhangsan
    # 11

 

 

2.6. Method (method)

Although the method is not a function, it can be understood as adding a shell outside the function.;After getting the actual function in the method, you can use the 2.5 section attribute.

  • __doc__: It is the same as the function.
  • __name__: It is the same as the function.
  • *__module__: It is the same as the function.
  • im_func: Using this property, you can get the reference of the actual function object in the method. In addition, if the version is more than 2.6, you can also use the attribute name __func__.
  • im_self: If it is bound (bound), then point to the class that called the method (if it is a class method) or instance (if it is an instance method), otherwise it is None. If it is more than 2.6, you can also use the attribute name __self__.
  • im_class: A class that actually invokes the method, or a class that actually invokes the instance of that method. Attention is not the class defined by the method, if there is an inheritance relation.

 Here are the general instance methods, and there are two special methods: class method (classmethod) and static method (staticmethod). Class methods or methods, but because they need to be called by class names, they are always bound.The static method can be seen as a function in the namespace of the class (a function called by the class name), which can only use the properties of the function, and can not use the properties of the method.

#coding:utf-8

class Dog(object):
    def imeth(self):
        print 'instance method ', self

    @classmethod
    def cmeth(cls):
        print 'class method ', cls

    @staticmethod
    def smeth():
        print 'static method '

dog = Dog()
dog.imeth() #Instance call binding method
Dog.imeth(dog) #Class invocation unbound method

Dog.cmeth() # Class call class method
Dog.smeth() # Class call static method

# Examples can also call class methods and static methods, but it doesn't make much sense. Class methods still bind the classes themselves.
dog.cmeth()
dog.smeth()

print '============================'


print dog.imeth.__self__ #<__main__.Dog object at 0x7f9a69d04e10>
print Dog.imeth.__self__ #None Unbound
print Dog.cmeth.__self__ #<class '__main__.Dog'>
print dog.cmeth.__self__ #<class '__main__.Dog'> It doesn't make sense to invoke a class method by using instances.
#print Dog.smeth.__self__ # A static method can be understood as a function (function) in a class, so there is no __self__.

 

2.7. Generator (generator)

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

  • __iter__: It’s just an Iterable mark.
  • gi_code: The generator corresponding to the code object.
  • gi_frame: The generator corresponding to the frame object.
  • gi_running: Whether the generator function is being executed. The generator function is in frozen state after yield and the next line of yield execution. The value of this property is 0.
  • next|close|send|throw: This is a number of callable methods that do not contain metadata information, and how to use them to view the relevant documents of the generator.

 

#coding:utf-8

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

Next, we discuss several types of built-in objects that are not commonly used. These types should have little contact with normal coding process unless you are implementing an interpreter or development environment yourself. So there are only a few attributes listed here. If you need a complete property table or you want to know more about it, you can see it.The reference documents listed at the end of the article.

2.8. Code block (code)

The code block can be compiled from class source code, function source code, or a simple statement code. Here we only consider the situation when it refers to a function; in the 2.5 section, we mentioned that we can use the func_code property of the function to get it. The attributes of code are all read-only.

  • co_argcount: The total number of common parameters does not include * parameter and * parameter.
  • co_varnames: All parameter names (including * parameter and * parameter) and tuple of local variable names.
  • co_filename: The name of the file in which the source code is located.
  • co_flags:  This is a numeric value, and every binary bit contains specific information. More attention is paid to 0b100 (0 x 4) and 0b1000 (0 x 8), if co_flags & 0b100! = 0, indicating the use of *args parameters; if co_flaGS & 0b1000! = 0, indicating the use of **kwargs parameters. In addition, if co_flags & 0b100000 (0 x 20) = 0, this is a generator function (generator).Function)

My understanding is that code represents some of the characteristics of classes and function codes themselves.

#coding:utf-8

def foo(name, age=11, home='CHN', *args, **kwargs):
    inner = 'inner'
    
co = foo.func_code
print co.co_argcount #3 Common parameter name age home
print co.co_varnames 
# ('name', 'age', 'home', 'args', 'kwargs', 'inner')
print co.co_flags & 0b100 #4 It shows that *args has been used

2.9. Stack frame (frame)

The stack frame represents a frame in the function call stack of the program runtime. The function has no attribute to get it, because it will be generated when function is called.The generator is returned by the function call, so there are attributes pointing to the stack frame (I understand that the generator is dynamic).。If you want to get a function related stack frame, you must get it when you call this function and this 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 get the current stack frame. This is listed hereAll the attributes come only read-only.

  • f_back: The previous frame of the call stack.
  • f_code: The code object corresponding to the stack frame.
  • f_locals: When you use the current stack frame, it is the same as the built-in function locals (), but you can first get other frames and use this property to get the locals () of that frame.
  • f_globals: It is the same as the built-in function globals () in the current stack frame, but you can get other frames first.

2.10. Tracking (traceback)

Traceback is an object that is used for backtracking when an exception occurs, which is opposite to the stack frame. Because the exception is built, and the exception is not captured, it will always be thrown out of the stack frame, so it is necessary to use try to see this object. You can use the exc_info () function of the sys module to get it, this function.Returns a tuple whose elements are exception types, exception objects, and traceback. The attributes of traceback are all read-only.

  • tb_next: The next tracking object that is tracked.
  • tb_frame: The corresponding stack frame is currently traced.
  • tb_lineno: The line number of the current tracking.

 

 

3. Using the inspect module

inspectThe module provides a series of functions to help use introspection. Below are only some of the more commonly used functions. To get all the function data, you can view the document of inspect module.

3.1. Check object type

 

  • is{module|class|function|method|builtin}(obj): Check whether objects are modules, classes, functions, methods, built-in functions or methods.

 

 

  • isroutine(obj):  It is used to check whether the object is function, method, built-in function or method and so on. This method is more convenient than multiple is* (), but its implementation still uses multiple is* ().

 

#coding:utf-8
import inspect

print inspect.ismodule(inspect) #True
print inspect.isfunction(inspect.isfunction) #True
print inspect.isbuiltin(sorted) #True
print inspect.isroutine(sorted) #True

 

For instance instances that implement __call__, this method returns False. If you want to call True directly, you can use it.isinstance(obj, collections.Callable)This form. I don’t know why Callable will be in collections module, sorry! I guess it is probably because the collections module contains many other ABC (Abstract Base Class) reasons:

 

#coding:utf-8
import collections

class Dog(object):
    def __call__(self, name):#Implementing the __call__ method can invoke the object directly.
        print 'i am a dog named ' , name

dog = Dog()
dog('DaHuang')

print isinstance(dog, collections.Callable) #True

print dog.__class__.__bases__

3.2. Obtaining object information

  • getmembers(object[, predicate]): This method is an extended version of dir (), which returns the properties corresponding to the name found in dir (), and looks like [(name, value),…]. In addition, predicate is a reference to a method. If specified, value should be used as reference.Number and return a Boolean value. If False, the corresponding attribute will not return. Using is* as the second parameter, you can filter out the attributes of the specified type.
  • getmodule(object):Are you sorry that the __module__ attribute in the second section returns only the string? This method will certainly satisfy you, and it returns to the module object defined by object.
  • get{file|sourcefile}(object):Get the file name of the module defined by object and the source code file name (if not, then return to None). TypeError exceptions are thrown when used for built-in objects (built-in modules, classes, functions, methods).
  • get{source|sourcelines}(object):Gets the source code of the object definition and returns it by the string string string list.The IOError exception is thrown when the code is unaccessible. Can only be used for module/class/function/method/code/frame/traceack objects.
  • getargspec(func): Only for methods, get the parameters of the method declaration and return to tuples, which are (list of common parameter names, * parameter names, * parameter names, default value tuples). If there is no value, it will be an empty list and 3 None. If it is more than 2.6, it will return a named tuple (Named).Tuple), in addition to indexing, you can use attribute names to access elements in tuples.
#coding:utf-8
import inspect
from a import *

print inspect.getmembers(Cat, inspect.ismethod)
#[('__init__', <unbound method Cat.__init__>), ('sayHi', <unbound method Cat.sayHi>)]

print cat.__module__ #str
print inspect.getmodule(cat) #<module 'a' from '/tmp/zc/a.pyc'> module object

print inspect.getfile(Cat) #/tmp/zc/a.pyc

print inspect.getsource(Cat) # Back to the source code (think this cool!!!)
"""
class Cat(object):
    def __init__(self, name='Kitty'):
        self.name = name

    def sayHi(self):
        print self.name, 'says Hi!'
"""
class Dog(object):
    def foo(self, name, age=11, home='CHN', *args, **kwargs):
        pass


print inspect.getargspec(Dog.foo)
#ArgSpec(args=['self', 'name', 'age', 'home'], varargs='args', keywords='kwargs', defaults=(11, 'CHN'))

 

getmro(cls): 
Returns a type tuple, and finds the class attribute according to the order in this tuple. If it’s a new class, it’s the same as the cls.__mro__ result. However, the old class does not have the property of __mro__, and this property can be used to report exceptions directly, so this method still has its value.

 

#coding:utf-8
import inspect

class A(object):
    pass

class B(object):
    pass

class C(A, B):
    pass

print inspect.getmro(C) 
print C.__mro__
print C.mro()
"""
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>)
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>)
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>]
"""

 

 
 

Leave a Reply

Your email address will not be published. Required fields are marked *