Python must encapsulate basic code ~Python function

Hello everyone, I'm Spicy

Recently, many fans found spicy strips at the end of the article and asked me to share some code to encapsulate this piece of content. Today he is here~
I can't read it once and put it away and read it slowly. What I wrote is still very detailed, and it must be easy to grasp. Python function, but please remember to support a lot of spicy bars, code words are not easy~
insert image description here

1. How to use functions

​ First define and then call. In the definition stage, only the syntax is detected, and the code is not executed. In the
calling stage, the code is executed. The function has
a return value
.

2. Default parameter trap

2.1 For mutable data types, immutability is not affected

def c(a=[]):
    a.append(1)
    print(a)
c()
c()
c()
结果:
[1]
[1, 1]
[1, 1, 1]
def c(a=[]):
    a.append(1)
    print(a)
c([])
c([])
c([])
结果:
[1]
[1]
[1]

3. Namespaces and scopes

​ Namespace is the place (memory space) used to store the binding relationship between names and
values The name life cycle that comes with the python interpreter: it takes effect when the interpreter is started, and invalid when the interpreter is closed . After the completion, the local namespace is invalid: the name defined in the function Life cycle: the local namespace of the function is only temporarily generated when the function is called, and the loading order is invalid after the function is called. Built-in->global->local search name order Search up based on the current location Assuming that you are currently standing locally, the search order: local -> global -> built-in Assuming that you are currently standing in the global, the search order: the search order of global -> built-in names is fixed in the function definition stage (that is, the search order of names has been determined when the grammar is detected), regardless of the calling position of the function













That is to say, no matter where you call a function, you must go back to the location where the function was originally defined to determine the lookup relationship of the name.

Scope: Scope refers to the scope of action
Global scope: Contains names in the built-in namespace and global namespace
Features: Globally valid, global survival
Local scope: Contains names in the local namespace
Features: Locally valid, temporary survival
global: Declare a name locally from the global scope and can be used to modify the global immutable type locally nonlocal
: Declare a name from a scope outside the current layer, you can use to locally modify the immutable type of the outer function

4 Closure functions:

It is defined inside the function and contains a reference to the scope name of the external function. It is necessary to combine the concept of function object to return the closure function to the global scope for use, thereby breaking the hierarchical restriction of the function. The
closure function provides a way for the function body pass-by-value solution

def func():
    name='egon'
    def inner():
        print(name)
    return inner
inner = func()
inner()

5 Parameters of the function

5.1 Definition Phase

​ Positional parameters The default parameters
of the formal parameters defined in order from left to right in the definition stage have been initialized with keyword parameters in the definition stage Free topic Variable-length parameter args overflow positional parameters, packed into tuples , Name the keyword parameter of the variable name that is accepted and assigned to args. The parameters placed between * and must be passed in the form of key=value. The variable-length positional parameter kwargs overflows the keyword argument, and packs it into a dictionary. Accept to **, assign the variable kwargs to the formal parameter and the actual parameter relationship: when the function is called, the value of the actual parameter will be bound to the variable name of the formal parameter, this binding relationship will take effect temporarily, and will become invalid after the call ends. span










5.2 The call phase

​ Positional arguments
In the calling phase, the incoming values ​​passed in from left to right will correspond to the formal parameters
. If there is * in the parameter, it will be broken up into positional arguments before passing the value, and then the ** with the actual parameter will be assigned . Before passing the value, it will be broken up into keyword arguments, and then assigned.


6. Decorators: Application of Closure Functions

insert image description here
A decorator is a tool used to add new functions to the decorated object
**Note: **The decorator itself can be any callable object, and the decorated object can also be any callable object.
Why use the decorator
** open Closure principle: **Closed means closed to modification and open to extension

6.1 The implementation of decorators must follow two principles:

​ 1. Do not modify the source code of the decorated object`
2. Do not modify the calling method of the
decorated object The goal of the decorator is to add new functions to the decorated object under the premise of following the principles 1 and 2

6.2 Decorator syntax sugar


Write the name of the @decorator on a separate line just above the object being decorated The result of the decorator call is assigned to the original function name foo=auth(foo) In this case, foo is the closure function wrapper

6.3 No-parameter decorator

import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
        return res
    return wrapper

@timmer
def foo():
    time.sleep(3)
    print('from foo')
foo()

6.4 Argument decorators

def auth(driver='file'):
    def auth2(func):
        def wrapper(*args,**kwargs):
            name=input("user: ")
            pwd=input("pwd: ")

        if driver == 'file':
            if name == 'egon' and pwd == '123':
                print('login successful')
                res=func(*args,**kwargs)
                return res
        elif driver == 'ldap':
            print('ldap')
    return wrapper
return auth2

@auth(driver='file')
def foo(name):
    print(name)

foo('egon')

7. Topics

#题目一:
db='db.txt'
login_status={
    
    'user':None,'status':False}
def auth(auth_type='file'):
    def auth2(func):
        def wrapper(*args,**kwargs):
            if login_status['user'] and login_status['status']:
                return func(*args,**kwargs)
            if auth_type == 'file':
                with open(db,encoding='utf-8') as f:
                    dic=eval(f.read())
                name=input('username: ').strip()
                password=input('password: ').strip()
                if name in dic and password == dic[name]:
                    login_status['user']=name
                    login_status['status']=True
                    res=func(*args,**kwargs)
                    return res
                else:
                    print('username or password error')
            elif auth_type == 'sql':
                pass
            else:
                pass
        return wrapper
    return auth2

@auth()
def index():
    print('index')

@auth(auth_type='file')
def home(name):
    print('welcome %s to home' %name)


# index()
# home('egon')

#题目二
import time,random
user={
    
    'user':None,'login_time':None,'timeout':0.000003,}

def timmer(func):
    def wrapper(*args,**kwargs):
        s1=time.time()
        res=func(*args,**kwargs)
        s2=time.time()
        print('%s' %(s2-s1))
        return res
    return wrapper


def auth(func):
    def wrapper(*args,**kwargs):
        if user['user']:
            timeout=time.time()-user['login_time']
            if timeout < user['timeout']:
                return func(*args,**kwargs)
        name=input('name>>: ').strip()
        password=input('password>>: ').strip()
        if name == 'egon' and password == '123':
            user['user']=name
            user['login_time']=time.time()
            res=func(*args,**kwargs)
            return res
    return wrapper

@auth
def index():
    time.sleep(random.randrange(3))
    print('welcome to index')

@auth
def home(name):
    time.sleep(random.randrange(3))
    print('welcome %s to home ' %name)

index()
home('egon')

#题目三:简单版本
import requests
import os
cache_file='cache.txt'
def make_cache(func):
    def wrapper(*args,**kwargs):
        if not os.path.exists(cache_file):
            with open(cache_file,'w'):pass

        if os.path.getsize(cache_file):
            with open(cache_file,'r',encoding='utf-8') as f:
                res=f.read()
        else:
            res=func(*args,**kwargs)
            with open(cache_file,'w',encoding='utf-8') as f:
                f.write(res)
        return res
    return wrapper

@make_cache
def get(url):
    return requests.get(url).text


# res=get('https://www.python.org')

# print(res)

#题目四:扩展版本
import requests,os,hashlib
engine_settings={
    
    
    'file':{
    
    'dirname':'./db'},
    'mysql':{
    
    
        'host':'127.0.0.1',
        'port':3306,
        'user':'root',
        'password':'123'},
    'redis':{
    
    
        'host':'127.0.0.1',
        'port':6379,
        'user':'root',
        'password':'123'},
}

def make_cache(engine='file'):
    if engine not in engine_settings:
        raise TypeError('egine not valid')
    def deco(func):
        def wrapper(url):
            if engine == 'file':
                m=hashlib.md5(url.encode('utf-8'))
                cache_filename=m.hexdigest()
                cache_filepath=r'%s/%s' %(engine_settings['file']['dirname'],cache_filename)

                if os.path.exists(cache_filepath) and os.path.getsize(cache_filepath):
                    return open(cache_filepath,encoding='utf-8').read()

                res=func(url)
                with open(cache_filepath,'w',encoding='utf-8') as f:
                    f.write(res)
                return res
            elif engine == 'mysql':
                pass
            elif engine == 'redis':
                pass
            else:
                pass

        return wrapper
    return deco

@make_cache(engine='file')
def get(url):
    return requests.get(url).text

# print(get('https://www.python.org'))
print(get('https://www.baidu.com'))


#题目五
route_dic={
    
    }

def make_route(name):
    def deco(func):
        route_dic[name]=func
    return deco
@make_route('select')
def func1():
    print('select')

@make_route('insert')
def func2():
    print('insert')

@make_route('update')
def func3():
    print('update')

@make_route('delete')
def func4():
    print('delete')

print(route_dic)


#题目六
import time
import os

def logger(logfile):
    def deco(func):
        if not os.path.exists(logfile):
            with open(logfile,'w'):pass

        def wrapper(*args,**kwargs):
            res=func(*args,**kwargs)
            with open(logfile,'a',encoding='utf-8') as f:
                f.write('%s %s run\n' %(time.strftime('%Y-%m-%d %X'),func.__name__))
            return res
        return wrapper
    return deco

@logger(logfile='aaaaaaaaaaaaaaaaaaaaa.log')
def index():
    print('index')

index()

Guess you like

Origin blog.csdn.net/AI19970205/article/details/123921771