Do-it-yourself Python framework: 4. Path mapping-1

Considering only simple path mappings, some simple regular expressions are involved. The mapping in web.py uses a list, and each mapping has two elements. For the convenience of writing code, use a dictionary directly. Before we start the content, let's do some homework.

globals trick

Give you a name, how to check if there is a class with the same name and then create an instance?

import inspect

class TestA:
    def info(self):
        print('TestA')
    
def create(cls_name):
    g = globals()
    if cls_name in g:
        if inspect.isclass(g[cls_name]):
            return g[cls_name]()
    return None
    
ta = create('TestA')
tb = create('TestB')
ta.info()
print(tb)

In Python, every time you define a class and add a variable, a name mapping will be added globally for easy lookup during execution. Use globals() to return all names and corresponding objects contained in the current code. So g['TestA']() and TestA() are equivalent. And TestB returns None because there is no such class globally. inspect.isclass is to judge whether a variable is a class.

URL parsing

The standard format of the URL is as follows. The urllib library of Python provides the urlparse function to help us quickly parse the URL.

from urllib.parse import urlparse

url = 'http://www.xyz.com/abc/def;params?a=1&b=2&c=zzz#fragment'
p = urlparse(url)
print('scheme: ' + p.scheme)
print('netloc: ' + p.netloc)
print('path: ' + p.path)
print('params: ' + p.params)
print('query: ' + p.query)
print('fragment: ' + p.fragment)

 After execution, you can see the information of each part as follows:

scheme: http
netloc: www.xyz.com
path: /abc/def
params: params
query: a=1&b=2&c=zzz
fragment: fragment

regular expression match

In mapping, we define the rules for path matching, and the specific implementation is to use regular expression matching. web.py is designed with efficiency in mind, and caches the matching of regular expressions. The specific implementation can be seen in the implementation of the Memoize class in the source code utils.py. Let's simplify the code here, assuming that the mapping is ('^/index/name=(.*)&age=(.*)$', 'index'), and the path entered now is /index/name=ZV&age=18. We can complete path matching and obtain parameters through the following code.

import re

class proxy:
    def __init__(self):
        self.match = None
        
    def __call__(self, match):
        self.match = match
        
def match(pattern, cls, value):
    p = proxy()
    compiled = re.compile(pattern)
    compiled.sub(p.__call__, value)
    cls, args = compiled.sub(cls, value), p.match
    return cls, args

if __name__ == '__main__':
    pattern = '/index/name/(.*)/age/(.*)'
    cls = 'index'
    value = '/index/name/ZV/age/18'
    cls, args = match(pattern, cls, value)
    print('Class:' + cls)
    if args:
        print('Args: ' + str([x for x in args.groups()]))

Program execution result:

Class:index
Args: ['ZV', '18']

After understanding these prerequisites, in the next chapter we will add URL mapping functionality to the framework.

Guess you like

Origin blog.csdn.net/panda_lin/article/details/121693377