Python基础(三)

Python基础4

装饰器

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象,装饰器是高阶函数与嵌套函数的集合。
概括的讲,装饰器的作用就是为已经存在的函数或对象添加额外的功能

示例(一)

import time


def timer(func):
    def timerr(*args,**kwargs):
        starttime=time.time()
        res=func(*args,**kwargs)         #此处res是为了接收a函数的返回值
        stoptime=time.time()
        print('总耗时 {}'.format(stoptime-starttime))
        return res
    return timerr

@timer     #相当于a=timer(a)
def a(name):
    time.sleep(3)
    print('My name is {}'.format(name))
    return 'a函数运行完毕'

@timer
def b():
    time.sleep(2)
    print('the in b fun')

print(a('zyl'))
b()

示例(二)
不同的函数使用不同的功能

import time


def auth_user(user,passwd):
    username = input('用户名:').strip()
    password = input('密码:').strip()
    if username == user and password == passwd:
        print('\033[32;1m认证成功\033[0m')
        return True
    else:
        print('\033[31;1m认证错误\033[0m')
        return False
        
def timer(auth_type):
    def auth(func):
        def timerr(*args,**kwargs):
            if auth_type == 'local':
                if auth_user('zyl','123456'):
                    func(*args, **kwargs)
            elif auth_type == 'ldap':
                if auth_user('wq','abcdef'):
                    func(*args, **kwargs)

        return timerr
    return auth


def index():
    print('in the index')

@timer(auth_type='local')   #bbs=timer(local)(bbs)
def bbs():
    print('in the bbs')

@timer(auth_type='ldap')
def home():
    print('in the home')

index()
bbs()
home()

python对象销毁(垃圾回收)说明

对象的引用计数变为0时,它被垃圾回收。但是回收不是"立即"的,由解释器在适当的时机,将垃圾对象占用的内存空间回收。

迭代器&生成器

生成器
定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:
示例(一):

a=(i*2 for i in range(10))
a.__next__()

generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。
当然,上面这种不断调用next(g)实在是太变态了,正确的方法是使用for循环,因为generator也是可迭代对象,for循环调用next可以自己定位到结束位置。
示例(二):

def fun(max):
    n,b,c=0,0,1
    while n<max:
        yield c
        b,c=c,b+c
        n+=1
for i in fun(10):
    print(i)

示例(三):

def fun(max):
    n,b,c=0,0,1
    while n<max:
        yield c
        b,c=c,b+c
        n+=1

a=fun(10)

while True:
    try:
        print(next(a))
    except StopIteration as e:
        print(e.value)
        break

yield 保存了函数的中断状态,next只会唤醒中断的函数,而send不仅会唤醒中断的函数还会传递一个值给yield.

yiled并行示例:

import time

def consumer(name):
    print('{},准备吃包子了'.format(name))
    while True:
        baozi=yield
        print('{}馅包子来了,被{}吃掉了'.format(baozi,name))
        
def producer(name):
    a=consumer('wq')
    a.__next__()
    b=['韭菜','大蒜','狗肉','方便面','洗发膏']
    for i in b:
        time.sleep(1)
        print('{}做了一个{}馅包子'.format(name,i))
        a.send(i)

producer('zyl')

列表生成式
生产的数据保存在全部内存中,占用内存空间
示例:

def fun(i):
    a=i*3
    return '{}的三倍是 {}'.format(i,a)

print([fun(i) for i in range(10) ])

迭代器
我们已经知道,可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
可以使用isinstance()判断一个对象是否是Iterable对象:

>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance(100, Iterable)
False

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件。
特点:

  • 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
  • 不能随机访问集合中的某个值 ,只能从头到尾依次访问
  • 访问到一半时不能往回退
  • 便于循环比较大的数据集合,节省内存

可以使用isinstance()判断一个对象是否是Iterator对象:

>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False

生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的,将list、dict、str等Iterable变成Iterator可以使用iter()函数:

>>> isinstance(iter([]), Iterator)
True

内置方法

abs()  取绝对值
>>> abs(-1)
1

all()  判断可迭代对象中的值是否为真,为真返回True,如果有一个值非真则返回False。
>>> all([1,0])
False
>>> all([1,2])
True

any()判断可迭代对象中的值有一个为真则返回真。
>>> any([1,0])
True
>>> any([0,0])
False

bin()十进制转为二进制
>>> bin(11)
'0b1011'

bool()判断真假,零或空序列都为假。
>>> bool([])
False
>>> bool(0)
False
>>> bool('')
False
>>> bool({})
False
>>> bool(1)
True

callable()判断值是否可以调用,函数,类等后面可以加括号。
>>> def a():
...     print(1)
...
>>> callable(a)
True
>>> callable(b)
False

chr()输入一个数字,解析成对应的assii码
>>> chr(300)
'Ĭ'
>>> chr(999)
'ϧ'
>>> chr(9999)
'✏'

ord()输入一个assii码解析成对应的数字
>>> ord('a')
97
>>> ord('b')
98
>>> ord('✏')
9999

exec()执行字符串代码。
>>> c='for i in range(3):print(i)'
>>> exec(c)
0
1
2

dir()可以查看一个数据类型内置方法,如列表,元组,字典等。

divmod()返回商和余数。
>>> divmod(10,3)
(3, 1)

filter()过滤出你想要的数据。
>>> res=filter(lambda n:n>5,range(10))
>>> for i in res:print(i)
...
6
7
8
9
>>> isinstance(res,Iterator)
True

map()它接收一个函数和一个列表,并通过把列表的每个元素依次应用到函数函数上,得到一个迭代器。
>>> res=map(lambda n:n*5,range(10))
>>> for i in res:
...     print(i)
...
0
5
10
15
20
25
30
35
40
45
>>> isinstance(res,Iterator)
True

hash()将一段字符转为不变的,每次一样的数字,退出程序后下次会改变。
>>> hash('zyl')
-228675803
>>> hash('zyl')
-228675803

hex()转为16进制
>>> hex(15)
'0xf'

id()返回内存地址。
>>> a=1
>>> id('a')
47201312

oct()转为8进制
>>> oct(9)
'0o11'


pow()返回一个次方的值
>>> pow(3,3)
27

isinstance() 判断一个对象的类型
>>> isinstance([],list)
True


repr()将一个对象转换为字符串格式。
>>> a=[1,2,3]
>>> repr(a)
'[1, 2, 3]'

round()输入一个浮点数,只保留几位小数。
>>> round(1.234,2)
1.23

sorted()排序,默认以键排序,数据类型不能混用,如字符串与数字同时存在。
例:修改使其以valus排序
>>> a={3:4,-1:2,-3:5,2:-1}
>>> sorted(a.items(),key=lambda x:x[1])    #key是关键字。

zip()将两个对象合并起来,合并完以后就变成了迭代器。
>>> a=(1,2,3)
>>> b='abc'
>>> for i in zip(a,b):
...     print(i)
...
(1, 'a')
(2, 'b')
(3, 'c')

eval()将字符串str当成有效的表达式来求值并返回计算结果,只能计算简单的,有判断语句就执行不了了。  
>>> a='[1,2,3]'
>>> print(type(eval(a)))
<class 'list'>

使用eval可以将一个str格式转为一个函数
例:a1=['a','b']
  def a():
	print(1)
  eval(a1[0])()     #现在就可以直接运行a函数了。
  
bytearray()使二进制字符串,可根据ascll码的排列数字(0-255)来修改
frozenset()将集合转换为不可变类型。
globals()输出程序中所有的全局变量和值,不会输出函数内的值
iter()将可迭代对象转换为迭代器。
local()打印出函数的内部所有变量。

Json&Pickle数据序列化
用于序列化的两个模块

  • json,用于字符串 和 python数据类型间进行转换
  • pickle,用于python特有的类型 和 python的数据类型间进行转换
json将文件中字符串以原有的格式读取出来,而不是str格式,只支持简单的格式。
例:import json
   zyl={1:'a',2:"b"}
  with open('new.py','w') as f:
     f.write(json.dumps(zyl))
  with open('new.py','r') as f:
     a=json.loads(f.read())
     print(a,type(a))
pickle和json一样但是存储的是二进制,Pickle只有在Python中可以使用。
例;import pickle
    zyl={1:'a',2:"b"}
    with open('new.py','wb') as f:
        f.write(pickle.dumps(zyl))
    with open('new.py','rb') as f:
        a=pickle.loads(f.read())
        print(a[1],type(a)) 
##loads与load区别:
  with open('info','rb+') as f:
    pickle.dump(b,f)
    f.seek(0)
    a=pickle.load(f)
    print(a['a'])

从当前目录导入其他目录的py文件

BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

from core import main  ##如果main模块中也要导入同级目录下的其他模块,也要使用from core import 模块名,而不能直接import 模块名

每日练习
模拟实现一个ATM + 购物商城程序

  • 额度 15000或自定义
  • 实现购物商城,买东西加入 购物车,调用信用卡接口结账
  • 可以提现,手续费5%
  • 支持多账户登录
  • 支持账户间转账
  • 记录每月日常消费流水
  • 提供还款接口
  • ATM记录操作日志
  • 提供管理接口,包括添加账户、用户额度,冻结账户等。。。
  • 用户认证用装饰器

代码如下:
https://github.com/BigSleepDragon/Python/tree/master/ATM

posted @ 2019-02-18 12:00  SleepDragon  阅读(168)  评论(0编辑  收藏  举报