Reflection of Python Advanced Usage

Posted by phpfreakjav on Sat, 11 May 2019 22:11:59 +0200

1. What is reflection?

In the process of program development, we often encounter the requirement that a method in the executing object, or a variable in the calling object, or a field of the object should be assigned, while the method name or field name can not be determined when encoding the code, and need to be input in the form of passing strings through parameters. For example, when we need to implement a general DBM framework, we may need to assign fields to data objects, but we can not predict what fields the data objects used in this framework have. In other words, we need to access unknown properties through some mechanism when we write the framework. At this point, we need a special method or mechanism to access or manipulate the unknown method or variable. This mechanism is called reflection (which in turn lets the object tell us what he is), or introspection.

Reflection mechanism: The method or attribute of the object object object is mapped in the form of a string, and the object member can be manipulated (find or get or delete or add). In Python, everything is an object. Therefore, reflection can be imported into modules through strings, classes can be found through strings, functions, methods, attributes can also be mapped, and it can be manipulated, such as modifying attributes, executing functions, importing classes and so on.

Functions and methods retrieved by reflection can be called directly with parentheses as usual, and an instance can be constructed directly after the class is retrieved; however, the field retrieved cannot be directly assigned, because it is actually another reference pointing to the same place, and the assignment can only change the current reference.

2. Reflection method

Reflection relies on the following four methods to implement operations on object objects:

hasattr(obj,name_str)

Determine whether objec has the name_str method or attribute, return the BOOL value, return True with the name_str attribute, or return False.

Note: The name_str type must be a string

getattr(obj,name_str[,default])

Gets the method or function with the same name as name_str in the object object object object object, returns its property if it exists, returns the default value if it does not exist, and the default value is optional.

Note: If the method is acquired, the memory address of the method in the object is returned if it exists. If you want to run it, you need to use the "()" method.

setattr(obj,name_str,value) Set a value method or property named name_str for the object object object. Used to set attribute values. If the attribute does not exist, it is created in assignment first.
delattr(obj,name_str) Delete the name_str method or attribute in the object object object, which, contrary to the setattr function, must exist, or issue an AttributeError.

3. Use scenarios of reflection

Reflection is to call its corresponding function when only the class name or function name is known. Widely used:

  • Configuration file, dynamic import module/method
  • Route

3.1 Dynamic Import Module/Method

The import module has another usage: _import_ (module_str), and the parameter module_str is the name of the module to be imported.

Predefined person.py module:

class Person(object):
    CONST = "Say Hello"

    def walk(self):
        print("I can walk")

    def eat(self, food):
        print("can eat: {}".format(food))

Call module: entry.py

module_name = input("Please enter the module name:")
class_name = input("Please enter the class name:")
func_name = input("Please enter the function name:")
module = __import__(module_name) #Import the module you want to import through the input string
if hasattr(module, "Person"):
    cls = getattr(module, class_name, None) #Find the class you need from the import module
    if cls:
        instance = cls() #Instances of generated classes
        if hasattr(instance, func_name):
            func = getattr(instance, func_name) #Find the class method you need from the import module
            func() #Method in Execution Class
        else:
            print("No way was found.")
    else:
        print("No class was found")
else:
    print("No module found")

Another implementation method:

from person import Person

p = globals()['Person']()
p.walk()

3.2 routing

In web API design or API automation, we usually need to find the correct entry function based on the URL.

(1) In web design, url routing

For example, you need to perform a login operation based on the url

The sample directory structure is as follows:

Define the login module accout.py first

def login():
    print("login")

def logout():
    print("logout")

url routing module index.py

data = input("input url:") #Enter url, such as accout/login
data_array = data.split("/") #Get the module name and function name
userspace = __import__("backend." + data_array[0]) #Import module
accout = getattr(userspace, data_array[0]) #Obtain
func = getattr(accout, data_array[1]) #Getting function objects
func()

Running output:

input url:accout/login
login

Another more common way to implement it is:

url = input("input url:")  # Enter www.xxx.com/accout/fun to return the result of fun and 404 if it does not exist.
target_module, target_func = url.split('/')
# module = __import__('backend.'+target_module) #Using fromlist=True, you can import backend
module = __import__('backend.'+target_module, fromlist=True) #Using fromlist=True, you can import backend.accout.
func_name = url.split('/')[-1]
if hasattr(module, target_func): #Determine whether module contains target_func members
    target_func = getattr(module, target_func) #Get a reference to func_name
    target_func() #Execution function

(2) Calling different functions through different requests

Before using reflection:

import requests

class RestAPI(object):
    def get(self,url):
        res = requests.get(url)
        response = res.text
        return response

    def post(self,url):
        res = requests.post(url)
        response = res.text
        return response

# After using reflection
url = "http://www.baidu.com/"
method = input("Request method>>>:")
h = RestAPI()

if method.upper() == 'GET':
    result = h.get(url)
elif method.upper() == 'POST':
    result = h.post(url)
else:
    print('The way of request is incorrect....')

After using reflection optimization:

import requests

class RestAPI(object):
    def get(self,url):
        res = requests.get(url)
        response = res.text
        return response

    def post(self,url):
        res = requests.post(url)
        response = res.text
        return response

# After using reflection
url = "http://www.baidu.com/"
method = input("Request method>>>:")
h = RestAPI()

if hasattr(h,method):
    func = getattr(h,method)#Get method function pointer
    res = func(url)
    print(res)
else:
    print("Your request is incorrect...")

 

Reference:

https://blog.csdn.net/perfect1t/article/details/80825372

http://www.cnblogs.com/yyyg/p/5554111.html

https://www.cnblogs.com/huxi/archive/2011/01/02/1924317.html

 

 

Topics: Attribute encoding Python