经验拾忆(纯手工)=> Python好用深度技能工具介绍

栏目: Python · 发布时间: 5年前

单元素元祖:

a = (1)    # 这是整数1
a = (1,)   # 这才是元祖
也许这两行,你们当时疑惑过,并且现在也都知道了,当然重点并不在这里。。

我无聊的时候想过,为什么单元素元祖要这样设计 -> (1,)?
不多废话,看下面代码,自己理解:
    a = (3,)
    a = (3)
    
    a = (1+2)
    a = (1+2,)
    
    a = (1+2) + (3+4)
    a = (1+2,) + (3+4,)

注:
    这是我个人原创理解的一个微不足道的知识点,但是印象却特别深刻。
    因为我反向推测出 设计者为什么会设计出这种语法。
    (当然,也许我的推测和设计者当时的想法的并不一样~~~手动滑稽)

深/浅拷贝-copy/deepcopy(皮/肉)

"""
    最开始接触深浅拷贝的时候没太大感觉,只是普通的觉得避免数据污染就够了
    后来有一次用scrapy写爬虫的时候,层次太多导致内存有些顶不住。
    后来用的 deepcopy() 来 优化  scrapy 的 meta, 虽然效果不是特别明显,但是感觉深浅拷贝很有用
"""
    1. =号,不拷贝
        =号就意味着,引用指向同一个地址空间,‘敌动我动,敌不动我不懂’ 的感觉。 LOL一句话:"连体婴儿"~~
    2. copy:也称浅拷贝
        我用最简单的话解释一下:浅拷贝就是只能拷贝最外面的一层皮,来独立开辟空间使用,再深还是共用的
        eg:
            from copy import copy
            from copy import deepcopy
            
            a = [[1,2,3],[4,5,6]]
            b = deepcopy(a)
            b[0] = 0            # 这就是最外面的一层皮
            print(b)
            print(a)
    
    3. deepcopy:顾名思义了,深拷贝
       如果你听懂我上面的话,我感觉这个就更好理解了, 浅拷贝是皮,深拷贝那就是肉了呗。
       没错,无论套了几层的序列结构,每一层都是独立开辟空间,独立指向。
            from copy import copy
            from copy import deepcopy
            
            a = [[1,2,3],[4,5,6]]
            b = deepcopy(a)
            b[0][1] = 0    # 看清楚,这回就是里面的肉了, 深拷贝:你改哪里都行,哪里都与我无关
            print(b)
            print(a)

lambda黑科技

"""lambda相当于匿名函数,可以使代码简介,但有时也会被人唾弃,但我仍然喜欢用lambda"""

1. 试想:如果你想在lambda调用多个函数,该如何写?
    lambda: (print(1),print(2))    # 最外层加个括号即可
    
2. 如果你想让这个 lambda函数直接自执行,而不是通过赋予一个函数引用再执行?
    1. 这个也是我自己瞎鼓捣出来的。
    2. 虽然我JS水平很垃圾,但是我知道JS匿名函数有一种执行方式叫做 ‘自执行’。
    3. 把上面类比一下。
    
    看吧,这就是 Python 版的匿名函数自执行方法。
        Python版本: (lambda a:print(a))(1)        
        JS版:       (function(){})()

lambda的虚伪替代品-operator

"""
    据说这个模块可以替代lambda, 个人理解此模块并不那么太有实用价值,理解成本也偏高,
    建议:如果不喜欢lambda或者lambda用的很少的人,可以研究一下此模块。此模块的意图还是可以的。
    我还是喜欢使用 lambda
"""
直接上个例子:(字典基于Value来排序) 
    传统lambda写法:
        In [27]: a = {'1':6, '2':5, '3':4}
        In [28]: sorted(a.items(), key=lambda a:a[1])   # 看key= 这里
        Out[28]: [('3', 4), ('2', 5), ('1', 6)]
                                
    operator写法:
        from operator import itemgetter
        
        In [25]: a = {'1':6, '2':5, '3':4}
        In [26]: sorted(a.items(), key=itemgetter(1))   # 就是key= 这里有区别
        Out[26]: [('3', 4), ('2', 5), ('1', 6)]

如果上面两种新旧方法都很模糊,那么我再解释一下: 我认为上面能让人头疼的也就是 索引 1 了!!!!
    sorted, map这种高阶函数,我之前也单独讲过,它会把 一个序列的每一个元素用管道函数进行映射。
    
    sorted稍微特殊一点,它的管道函数方法变成了key=这里: (变相理解为 指定 排序 的基准/参考)
        1. key=lambda a:a[1]
            指定基准:序列a的 每子元素 的 第1号索引子元素    # eg: [[1,2],[3,4],[5,6]]  就是2,4,6
        
        2. key=itemgetter(1)
            指定基准:同上一模一样,只不过写法不一样,逻辑步骤就是 原原本本从 lambda那里演变过来的。
            
总结与个人观点:
    1. operator 模块只是 lambda 使用思想 的 高一层的封装
    2. 让使用者可以忽略lambda格式细节
    3. 但是我认为 如果lambda都用不好, 那么 这个 itemgetter(1) 这种子元素 索引的指定 也会很困难
    4. 所以我还是建议用 lambda, 当你 lambda思想练熟了之后, 用 operator看看官方文档就是很快的事情

封包/拆包(解构赋值)/函数占位参数骚操作

"""
    再次说明一下:我写的所有的都是Py3的/   Py2的解构赋值可能有些出入,此处我只说Py3
"""

封包:
    1)
        def f(a,*b):
            print(a)    # 1
            print(b)    # (2,3,4)
        f(1,2,3,4)
    2) 
        def f(**kwargs):
            print(kwargs)    # {'a': 3, 'b': 4}
        f(**dict(a=3,b=4))
        
拆包(解构赋值):
    """
        我说过太多次了, ES6的语法和Python很像。解构赋值这个词也是从ES6听到的。
        不过ES6的解构,还可以解构 {} 和 解构空值 和 解构默认值,   而Python不可以
    """
    1)  只要第一个
            a, *_ = range(5)
            print(a, _)     # 0  [1, 2, 3, 4]

    2)  只要第一个和最后一个
            a, *_, c = range(5)
            print(a, _, c)    # 0  [1, 2, 3]  4
            
    3)  只要最后一个
            *_, b = range(5)
            print(_, b)      # [0, 1, 2, 3]  4


函数占位参数骚操作:
    """
        这是我在源码中看到的,当时觉得很惊讶,自己试了一下,下面说下自己的理解:
        这个*的作用就是: (*后面的参数是 调用时 必须命名 且 必须传递 的参数)
            a你必须给我传过来,但是你不写   a=
            b你必须给我传过来,但是你必须写 b=
    """
    def f(a,*,b):
        print(a)
        print(b)
    f(1,b=3)    # f(a=1,b=3)    # 只能通过这两种方式调用

反射-getattr & setattr & hasattr & delattr & import_module

综合例子:
    from importlib import import_module
    random = import_module('random')          # 动态反射导入模块  
    # 或 random = __import__('random')         
    if hasattr(random, 'randint'):            # 检测模块中是否有函数
        randint = getattr(random,'randint')   # 动态反射导入函数
        print(eval('randint(0,1)'))               # 字符串转语句执行(类似反射)
    
getattr & setattr & hasattr & delattr 讲解:
    hasattr & getattr
        random = __import__('random')
        if hasattr(random,'randint'):    # 检测 random 模块中是否有 randint 函数
            randint = getattr(random,'randint')
            print(randint(0,1))
            
    delattr & hasattr 
        delattr(random, 'randint')      # 动态删除模块中的 randint函数
        if not hasattr(random,'randint'):
            print('没有此函数了,让delattr删除了')
            
    setattr & getattr                   # 动态重新设置模块的 randint函数,并给个函数体
        setattr(random, 'randint', lambda:print('设置这个方法凑合用把。'))
        randint = getattr(random, 'randint')
        randint()

模块重新导入到内存-reload

from imp import reload
import time
reload(time)
print(time.time())

进度条-tqdm

for x in tqdm(range(100)):
    import time
    time.sleep(1)
    print(x)
tqdm包装一个可迭代对象, 只是装饰了一下,使用方法还是像原来一样使用。

票数统计-Counter

In [2]: from collections import Counter

In [3]: Counter([1,2,3,4])
Out[3]: Counter({1: 1, 2: 1, 3: 1, 4: 1})

In [4]: Counter([1,1,1,2,2,3])    # 统计频次
Out[4]: Counter({1: 3, 2: 2, 3: 1})

In [5]: Counter([1,1,1,2,2,3]).most_common(1)    # 频次最多的前1个
Out[5]: [(1, 3)]

文件 复制/移动-shutil

import shutil
shutil.copy(源,目标)    # 复制
shutil.move(源,目标)    # 移动,改名
shutil.rmtree(r'目录名')  # 删除目录(级联删除)    # 参数只能是目录

文件遍历-os.walk

"""
    os.walk() 是一个深度遍历模式的文件遍历函数
    返回值是一个迭代器,遍历这个迭代器后,每一次的返回值都是如下顺序三种构成
        1. current_path: 当前路径 
        2. dir_list:     其下目录列表
        3. file_list:    其下文件列表
    
"""
import os
file_generator = os.walk('D:/虚拟E盘-代码空间/TF2')
for current_dir, dir_list, file_list in file_generator:
    print(current_dir, dir_list, file_list)

非阻塞执行cmd/shell-subprocess

"""
    主要代替os.system
""" 
import subprocess
res = subprocess.run('dir', shell=True, stdout=subprocess.PIPE) # 结果输入到res管道中去
print(res.stdout.decode('gbk'))    # res管道中有输出日志,如果在win下,需要 decode

排列组合-itertools模块

import itertools
list(itertools.product([1,2,3],repeat=3))    # 复制3份有序全排列, repeat=3    
list(itertools.permutations([1,2,3], 3))     # 内部有序排列, 3表示最后排列为几位
list(itertools.permutations([1,2,3,4],3))    # 无序组合, 3表示3位

枚举-emunerate

In [100]: list(enumerate(list('abcde'),start=1))    # 默认从0,开始标号, start=1就从1开始
Out[100]: [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')]

In [108]: list(enumerate(((1,2),(3,4))))
Out[108]: [(0, (1, 2)), (1, (3, 4))]        

In [106]: list(enumerate({"a":'c','b':'d'}))
Out[106]: [(0, 'a'), (1, 'b')]

global & nonlocal & globals() & locals()

global: 函数外的变量只能在函数内部取值,而不能修改, 如果想要在函数内部修改外部变量, ‘global 变量名’ 即可
    a = 1
    def f():
        global a
        a += 1
        print(a)
    f()
        
nonlocal: 原理同上一模一样,只不过应用场景是闭包了,代码如下:
    def f():
        a = 1
        def f1():
            nonlocal a
            a = a+1
            print(a)
        f1()
    f()

日历-calendar

import calendar
calendar.calendar(2019)    # 返回2019年的日历
calendar.month(2919,5)    # 返回2019年5月的日历
calendar.isleap(2000)    # 判断2000年是否为闰年

时间/日期-time/datetime

import time
1. 时间戳:
    time.time()
    
2. 字符串转时间(p-pass方便记忆)
    from datetime import datetime
    fordate = datetime.strptime('2019-5-25 9:30:30', '%Y-%m-%d %H:%M:%S')
    print(fordate)

3. 时间转字符串(f-from方便记忆)
    from datetime import datetime
    strdate = datetime.strftime(fordate, '%Y-%m-%d %H:%M:%S')
    print(strdate)
    
4. 初始化时间
    from datetime import datetime
    dt1 = datetime(2019,5,25,9,37)    # 初始化时间为 datetime格式
    dt1 = datetime.now()   # 获取当前时间为 datetime格式
    print(dt1.year)
    print(dt1.month)
    print(dt1.day)
    print(dt1.hour)
    print(dt1.minute)
    print(dt1.second)

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Art and Science of CSS

The Art and Science of CSS

Jonathan Snooks、Steve Smith、Jina Bolton、Cameron Adams、David Johnson / SitePoint / March 9, 2007 / $39.95

Want to take your CSS designs to the next level? will show you how to create dozens of CSS-based Website components. You'll discover how to: # Format calendars, menus and table of contents usin......一起来看看 《The Art and Science of CSS》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

html转js在线工具
html转js在线工具

html转js在线工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具