zoukankan      html  css  js  c++  java
  • 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('33[32;1m认证成功33[0m')
            return True
        else:
            print('33[31;1m认证错误33[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

  • 相关阅读:
    设置类库项目的程序集名称和默认命名空间
    网上购物系统(Task101)——业务逻辑层BLL(工厂模式实现热插拔)
    网上购物系统(Task102)——登录控件的使用(登录控件的基本配置)
    1.1.3 以类为单位的编程思想
    1.1.2 ADO.NET模型
    网上购物系统(Task100)——业务逻辑层BLL(面向接口的编程模式)
    ASP.NET(C#)命名规范(前缀)
    如果我说,类就是一个人,你会信吗?
    1.1.1 什么是ADO.NET
    [置顶] 编程就是用计算机语言写文章
  • 原文地址:https://www.cnblogs.com/SleepDragon/p/10394800.html
Copyright © 2011-2022 走看看