Python之路-4

1.1 装饰器、生成器、迭代器、调用函数、内置函数

1.1.1 装饰器

装饰器:本质势函数,(装饰其它函数)就是为其他函数添加附加功能。

原则:1、不能修改被被装饰的函数的源代码

              2、不能修改被装饰的函数的调用方式

实现装饰器的知识储备:

1、函数即“变量”

2、高阶函数

3、嵌套函数

高阶函数 + 嵌套函数 = 装饰器

下面举个列子:

【高级版】

import time     #申明库
def timer(func):    #定义timer函数
    def deco(*args,**kwargs):     #定义deco函数,(嵌套函数)
        start_time = time.time()    #获取func函数开始的时间
        func(*args,**kwargs)      #执行func函数
        stop_time = time.time()     #获取func函数结束的时间
        print('the func run time is %s'%(stop_time-start_time))     #打印func函数执行的总时间
    return deco     #在timer函数中返回deco地址变量
@timer  #装饰器  #test = timer(test)
def test():
    time.sleep(3)
    print('in the test')
test()

 

【终极版】

# -*- coding:utf-8 -*-
#!/usr/bin/env python
# Author:suchagal
username = 'xuwei'
password = 'suchagal'
def auth(auth_type):
    def outer_wrapper(func):
        def wrapper(*args, **kwargs):
            if auth_type == 'local':
                 users = input('input username:').strip()
                 passwd = input('input passwd:').strip()
                 if users == username and passwd == password:
                    res = func(*args, **kwargs)
                    print('33[32;1mwelcome to home33[0m')
                    return res
                 else:
                    exit('33[31;1minvalid input33[0m')
            elif auth_type == 'ldap':
                print('什么ldap,我不会。。。')
        return wrapper
    return outer_wrapper

@auth(auth_type = 'local') #home = auth(home)
def home(name):
    print('i am home',name)
    return 'xuwei'

@auth(auth_type = 'ldap')
def bbs():
    print('i am bbs')

home('daweige')
bbs()

 

这个装饰器的目的是提供不同的认证方式,可以再本地认认证们也可以在远端认证LDAP认证。装饰器传进去的参数的不同,来进行认证。

个人理解:装饰器本质就是将被装饰的函数“门牌号”传递给另一个函数的“门牌号”,然后通过修改该函数体来改变函数,最后再将“门牌号”传递回来。

1.1.2 调用函数

调用Python中的定义的函数(也就是不需要import就可以直接用的函数),可以在任何地方调用。

还有调用一些函数时是需要import的,这个应该是对应组件中的函数,比如:import re就可以调用正则函数;import sys就可以调用系统对应的函数;import os就可以调用目录结构的相关函数;import time就可以调用系统时间的相关函数;import copy就可以实现深copy(见5.1.7)。

调用自己写的函数,分为两种情况(目前我所知道的,知增录扩)

1、在相同的Python文件目录下

直接import Python的文件名,然后文件名.方法名();

2、在不同的Python文件目录下

先要添加上层目录地址,再from xxx import xxx;如下:

import os
import sys

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
from conf import settings
from core import main

 

1.1.3 生成器

列表生成器:

[i*2 for i in rangae(10)]

>>>[0 2 4 6 8 10 12 14 16 18]

原理:列表生成器在没有执行之前是“门牌号”储存在计算机内存中的,也就是说在计算机内存中不是“[0 2 4….]”。这样可以省内存!

再举个例子:

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

import time
def consumer(name):
    print('%s 准备吃包子啦!' %name)
    while True:
        baozi = yield
        print("包子[%s]来了,被[%s]吃了!" %(baozi,name))

def productor(prod_name):
    c = consumer('小明')
    c1 = consumer('小小明')
    c.__next__()       #执行一次consumer()函数
    c1.__next__()      #同上
    print("33[31;1m%s开始做包子了!33[0m" %prod_name)
    weidao = ['韭菜','大白菜','猪肉','牛肉','羊肉','空心菜','榨菜','小白菜','鸭肉','鸡肉']
    for i in weidao:
        time.sleep(1)
        print("做了两个包子")
        c.send(i)  #将weidao发送给baozi
        c1.send(i)     #同上

productor("小明")

上面的函数可以在单线线程下执行多线程的效果,这个就是nginx单线程会比其他多线程还要快几倍的原因!

1.1.4 迭代器

我们已经知道,可以直接作用于for循环的数类型有以下几种:

一类是集合数据类型,如list、tuple、dict、set、str等;

一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:iterable。

*可以使用isinstance()判断一个对象是否是iterable(迭代器)对象:

而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,知道最后抛出stopiteration异常错误表示无法集训返回下一个值。

可以被next()函数调用并不断返回下一个值的对象成为迭代器。

生成器一定是迭代器,迭代器不一定是生成器。

1.1.5 内置函数

print(abs(-7))  #取绝对值
print(all([1,2,3,4]))   #列表中的元素都为真返回true,有一个为假则返回false
print(any([0,0,0])) #列表中的元素都为假返回false,至少有一个则返回true
a = ascii([1,2,'xuwei','suchagal']) #将一个列表,字典,变成字符
print(type(a),[a])
b = eval('''[1,2,'xuwei','suchagal']''')    #取注释
print(b[2])
print(bin(34))  #十进制转二进制
print(bool(1))  #判断真假,也可以判断列表
print(bool([]))

a = bytes('abcde',encoding='utf-8') #str不可以修改
print(a.capitalize(),a)
b = bytearray('abcde',encoding='utf-8') #可以修改str
print(b[1])
b[1] = 101
print(b)

def ssaf():pass
print(callable(ssaf)) #可以调用返回true,不可调用返回false

print(chr(98)) #返回数字在ASCII码中对应的str
print(ord('b')) #返回ASCII中的str对应的数字

compile()  #将一串字符串代码执行(忘记它吧,没什么卵用)
exec() #可以将一个被注释的程序执行
eval() #去掉注释,并执行,被注释的部分非程序

dir()  #查看该类,字典有什么方法
dict(a=b,c=3)  #生成一个字典
divmod(5,3)    #返回一个5/3=(1,2)

res = filter(lambda n:n*n,range(10))
for i in res:
    print(i)

sas = map(lambda n:n*2,range(10))   #将后面range的值传个lambda处理,处理完了传给map
for ii in sas:
    print(ii)
print(sas)

import functools
res = functools.reduce(lambda x,y:x+y,range(10))
print(res)

a = frozenset([12,3,23,34,3,45,22,22])  #让集合没有怎删改查的选项

print(globals())    #显示出当前文件中的全局变量(字典类型)
print(locals()) #打印局部变量
print(hex(3234))    #将一个数字转成16进制

 The unexamined life is not worth living.--Socrates

浑浑噩噩的生活不值得过.

原文地址:https://www.cnblogs.com/suchagal/p/8477800.html