(四)第四次视频,2月5日春节期间

时间:2022-06-19 14:23:41

装饰器

def login(func):

    def inner(arg):
        print("passed user verification...")
        return func(arg)

    return inner

# 本段代码功能等效于tv = login(tv),执行了这段代码也不会发生什么,只是改变了tv的原有功能
# 是一种与语法糖的功能
@login
def tv(name):
    print("Welcome to TV page")

1、@login 

    执行login函数(由于@符号的特殊性),把自己装饰的函数的函数名当作参数,w1(tv)

     tv函数重新定义, tv = login(tv),这样一来tv就变成了inner。

2、以后执行tv的时候,就是执行inner函数了

#!/usr/bin/env python
#coding:utf-8

def Before(request,kargs):
    print('before')

def After(request,kargs):
    print('after')

# 装饰器框架多了一层,为了本身带参数...
def Filter(before_func,after_func):
    # print('haha')
    def outer(main_func):
        # print('yoyo')
        def wrapper(request,kargs):

            before_result = before_func(request,kargs)
            if(before_result != None):
                return before_result;

            main_result = main_func(request,kargs)
            if(main_result != None):
                return main_result;

            after_result = after_func(request,kargs)
            if(after_result != None):
                return after_result;

        return wrapper
    return outer

@Filter(Before, After)
def Index(request,kargs):
    print('index')

1、执行Filter函数,返回的是outer

2、于是就变成了@outer,然后按照装饰器的解释进行运行啦

    新Index =outer(Index), 即Index == wrapper

1、2步归纳起来就是执行了以下代码:

Index = Filter(Before, After)(Index)

3、以后执行Index的时候,就是执行wrapper函数了 


两个装饰器一起用:
# -*- coding:utf-8 -*-
import functools
def w1(*args1, **kwargs1):
    def outer(func):
        @functools.wraps(func)
        def wrapper1(*args, **kwargs):
            print('w1')
            print(args1)
            ret = func(*args, **kwargs)
            print(kwargs1)
            return ret
        return wrapper1
    return outer

def w2(*args1, **kwargs1):
    def outer(func):
        @functools.wraps(func)
        def wrapper2(*args, **kwargs):
            print('w2')
            print(args1)
            ret = func(*args, **kwargs)
            print(kwargs1)
            return ret
        return wrapper2
    return outer

@w1('d1', d1=1)
@w2('d2', d2=2)
def main(*args, **kwargs):
    print('main')
    return args, kwargs

ret = main('m', m=1)
print(ret)
print('main\'s name is '+main.__name__)
输出:
w1
('d1',)
w2
('d2',)
main
{'d2': 2}
{'d1': 1}
(('m',), {'m': 1})
main's name is main

Process finished with exit code 0

@functools.wraps(func)的功能是为了让函数名不是wrapper,做了类似于wrapper.__name__ = func.__name__这样的动作。
# -*- coding:utf-8 -*-
import functools


def wrapper(func):
    @functools.wraps(func)
    def wrapper():
        print('before')
        func()
        print('after')
    return wrapper

@wrapper
def foo():
    print('foo')

foo()
print('foo\'s name is '+foo.__name__)

最后给一个比较难得题目:
# 请编写一个decorator,能在函数调用的前后打印出'begin call'和'end call'的日志。
#
# 再思考一下能否写出一个@log的decorator,使它既支持:
#
# @log
# def f():
#     pass
# 又支持:
#
# @log('execute')
# def f():
#     pass
解答1,比较直观的解答:
import functools


def log(para):
    if callable(para):
        @functools.wraps(para)
        def wrapper(*args, **kw):
            print("start call {0}():".format(para.__name__))
            f = para(*args, **kw)
            print("end call {0}():".format(para.__name__))
            return f
        return wrapper
    else:
        def decorator(func):
            @functools.wraps(func)
            def wrapper(*args, **kw):
                print("{0} {1} ():".format(para, func.__name__))
                return func(*args, **kw)
            return wrapper
        return decorator


@log
def now1():
    print("2016-2-5")


@log('execute')
def now2():
    print("2016-2-5")

now1()
print('')
now2()
输出:
start call now1():
2016-2-5
end call now1():

execute now2 ():
2016-2-5

解答2,比较简短的解答,代码很漂亮:
import functools

# 最最漂亮的代码!!每一行都很漂亮
def log(arg):
    def decorator(func=arg):
        text='call' if func==arg else arg
        @functools.wraps(func)
        def wrapper(*args,**kw):
            print('%s %s():' % (text,func.__name__))
            return (func(*args, **kw),print('end %s %s():' % (text, func.__name__)))[0]
        return wrapper
    return decorator() if callable(arg) else decorator

@log('execute')
def now():
    print("2016-2-9")

@log
def hello():
    print('hello world!')

    
now()
print(now.__name__)
print()
hello()
print(hello.__name__)

输出:
execute now():
2016-2-9
end execute now():
now

call hello():
hello world!
end call hello():
hello


正则表达式

一个讲的不错的博客:  http://www.cnblogs.com/PythonHome/archive/2011/11/19/2255459.html
直接贴代码:
# -*- coding:utf-8 -*-

import re


pattern = r"\\section"
string = '\sectionxu'
m = re.match(pattern, string, re.IGNORECASE)
print(m)
print(m.group())

pattern = '[0-9]+'
m = re.match(pattern, 'u8us78jkjk')  # match只能从头开始匹配
if m:
    print(m.group())



pattern = '[0-9]{0,10}'
m = re.findall(pattern, 'u8us78jkjk')
print(m)

pattern = '[a-zA-Z]{1,10}'
m = re.findall(pattern, 'u8us78jkjk')
print(m)

pattern = '\w+'
m = re.findall(pattern, 'u8us7@#8jkjk')
print(m)

pattern = '\w+'
m = re.findall(pattern, 'u8us7@#8jkjk')
print(m)

pattern = '\d+'
m = re.search(pattern, 'u8us7@#8jkjk')  # search返回第一个找到的
print(m)
if m:
    print(m.group())

pattern = '\d+'
m = re.sub(pattern, '|', 'u8us7@#8jkjk', count=2)
print(m)
输出:
<_sre.SRE_Match object; span=(0, 8), match='\\section'>
\section
['', '8', '', '', '78', '', '', '', '', '']
['u', 'us', 'jkjk']
['u8us7', '8jkjk']
['u8us7', '8jkjk']
<_sre.SRE_Match object; span=(1, 2), match='8'>
8
u|us|@#8jkjk

再贴一段代码:
# -*- coding:utf-8 -*-
import re

p = re.compile('[a-z]+')  # p是一个_sre.SRE_Pattern
print(type(p))
m = p.match("tempo")    # m是一个# _sre.SRE_Match object
print(m)
print(m.group())
print(m.start())
print(m.end())
print(m.span())

print(''.center(50, '-'))
s = p.search('::: message')     # s是一个# _sre.SRE_Match object
print(s)
print(s.span())
print(s.group())

print(''.center(50, '-'))
p = re.compile('[a-z]+')
m = p.match('string goes here')
if m:
    print('Match found: ', m.group())
else:
    print('No match')

print(''.center(50, '-'))
p = re.compile(r'\d+')
f = p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
print(f)

iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
print(iterator)
for match in iterator:
    print(match)    # match是一个_sre.SRE_Match object
    print(match.span(), match.group())

m = re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998')
print(m)
print(m.span(), m.group())

s = re.search('}$', '{block}')
print(s.group())

p = re.compile(r'\bclass\b')
print(p.search('no class at all'))

print(50*'-')
p = re.compile('(ab)*')
m = p.match('ababababab')
print(m)
print(m.group(0,1))
print(m.span(1))

print(50*'-')
p = re.compile('(a(b)c)d')
m = p.match('abcd')
print(m.span(2))
print(m.groups())  # The groups() 方法返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

p = re.compile(r'(\b\w+)\s+\1')
print(p.search('Paris in the the spring').group())

m = re.match("(?:[abc])+", "abc")
print(m.groups())

print(50*'-')
p = re.compile(r'(?P<word>\b\w+\b)')
m = p.search( '(((( Lots of punctuation )))' )
print(m.group(1))
print(m.group('word'))

print(50*'-')
p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)')
s = p.search('Paris in the the spring')
print(s.group())
print(s.groups())

print(50*'-')
phone_str = "hey my name is alex, and my phone number is 13651054607, please call me if you are pretty!"
phone_str2 = "hey my name is alex, and my phone number is 18651054604, please call me if you are pretty!"
m = re.search("(1)([358]\d{9})",phone_str2)
if m:
    print(m.group())

print('计算器'.center(50, '-'))
val = '9-2*-5/3 + 7 /3*99/4*2998 +10 * 568/14'
mch = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val)
print(mch.group())

val = '1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
content = re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', val).group()
print(content)
输出:
<class '_sre.SRE_Pattern'>
<_sre.SRE_Match object; span=(0, 5), match='tempo'>
tempo
0
5
(0, 5)
--------------------------------------------------
<_sre.SRE_Match object; span=(4, 11), match='message'>
(4, 11)
message
--------------------------------------------------
Match found:  string
--------------------------------------------------
['12', '11', '10']
<callable_iterator object at 0x10f2081d0>
<_sre.SRE_Match object; span=(0, 2), match='12'>
(0, 2) 12
<_sre.SRE_Match object; span=(22, 24), match='11'>
(22, 24) 11
<_sre.SRE_Match object; span=(29, 31), match='10'>
(29, 31) 10
<_sre.SRE_Match object; span=(0, 5), match='From '>
(0, 5) From 
}
<_sre.SRE_Match object; span=(3, 8), match='class'>
--------------------------------------------------
<_sre.SRE_Match object; span=(0, 10), match='ababababab'>
('ababababab', 'ab')
(8, 10)
--------------------------------------------------
(1, 2)
('abc', 'b')
the the
()
--------------------------------------------------
Lots
Lots
--------------------------------------------------
the the
('the',)
--------------------------------------------------
18651054604
-----------------------计算器------------------------
2*-5
(-40.0/5)

旋转二维数组

# -*- coding:utf-8 -*-

array1 = [ i for j in range(3) for i in range(5)]
print(array1)

array2 = [j for j in range(3) for i in range(5)]
print(array2)

print()
matrix = [[row for col in range(5)] for row in range(5)]
for row in matrix:
    print(row)
# 矩阵翻转
print('矩阵翻转'.center(50, '-'))
inverse_matrix = [[matrix[col][row] for col in range(len(matrix))] for row in range(len(matrix[1]))]
for row in inverse_matrix:
    print(row)

# 下面的方法在一个矩阵原地翻转,只适用于方块阵
print('下面的方法在一个矩阵原地翻转,只适用于方块阵')
array=[[col for col in range(5)] for row in range(5)] #初始化一个4*4数组

for row in array: #旋转前先看看数组长啥样
    print(row)

print('-------------')
for i,row in enumerate(array):

    for index in range(i,len(row)):
        tmp = array[index][i]  # get each rows' data by column's index
        array[index][i] = array[i][index]
        print(tmp, array[i][index])  # = tmp
        array[i][index] = tmp
    for r in array:
        print(r)
    print('--one big loop --')
输出:
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]

[0, 0, 0, 0, 0]
[1, 1, 1, 1, 1]
[2, 2, 2, 2, 2]
[3, 3, 3, 3, 3]
[4, 4, 4, 4, 4]
-----------------------矩阵翻转-----------------------
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
下面的方法在一个矩阵原地翻转,只适用于方块阵
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
-------------
0 0
0 1
0 2
0 3
0 4
[0, 0, 0, 0, 0]
[1, 1, 2, 3, 4]
[2, 1, 2, 3, 4]
[3, 1, 2, 3, 4]
[4, 1, 2, 3, 4]
--one big loop --
1 1
1 2
1 3
1 4
[0, 0, 0, 0, 0]
[1, 1, 1, 1, 1]
[2, 2, 2, 3, 4]
[3, 3, 2, 3, 4]
[4, 4, 2, 3, 4]
--one big loop --
2 2
2 3
2 4
[0, 0, 0, 0, 0]
[1, 1, 1, 1, 1]
[2, 2, 2, 2, 2]
[3, 3, 3, 3, 4]
[4, 4, 4, 3, 4]
--one big loop --
3 3
3 4
[0, 0, 0, 0, 0]
[1, 1, 1, 1, 1]
[2, 2, 2, 2, 2]
[3, 3, 3, 3, 3]
[4, 4, 4, 4, 4]
--one big loop --
4 4
[0, 0, 0, 0, 0]
[1, 1, 1, 1, 1]
[2, 2, 2, 2, 2]
[3, 3, 3, 3, 3]
[4, 4, 4, 4, 4]
--one big loop --