pip 笔记

pip 和pip3 的区别

  • 如果系统中同时安装了Python2和Python3,则pip默认给Python2用,pip3指定给Python3用

  • 若只存在一个python版本,可以认为在用系统中pip和pip3命令都是相同的

更新依赖 pip3 install cloudscraper --upgrade 或者 -U

列出所有依赖 pip3 list

指定国内源

  • 临时,或在requirements.txt开头加一行

    1
    -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
  • 永久

    在pip.ini文件配置

1
2
3
4
[global]
index-url = https://pypi.doubanio.com/simple/
[install]
trusted-host = pypi.doubanio.com

​ pip全局配置

1
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

显示包信息 pip show xxx

自动跳过安装失败的包:pip install -r requirements.txt --ignore-installed

Win10 cmd 设置代理

1
2
set HTTP_PROXY=http://127.0.0.1:1080
set HTTPS_PROXY=http://127.0.0.1:1080

英文单词

  • iterable 可迭代(可用for遍历)
  • immutable 不可变
  • hashable 可哈希,不可变对象

文件头utf8作用

1
2
# -*- coding: UTF-8 -*-
# coding=utf-8

参考:https://blog.csdn.net/Daningliu/article/details/121617391

  • python2默认的编码格式是ASCII格式,python3默认的编码格式是utf-8格式
  • python2环境中编写代码时,如果代码(或者注释)有中文,则需要在文件的开头指定
  • python3环境中,源码文件默认使用utf-8编码,可以正常解析中文,不需要在开头指定
  • 为了代码的可移植性,还是建议在编写程序的时候加上

装饰器

装饰器本质上是一个函数,在不修改函数源码的情况下,给函数增添一些新功能,类似 hook

简单的计时装饰器

1
2
3
4
5
6
7
8
9
10
11
12
# 接收一个函数作为参数
def timer(func):
# *args,**kwargs,解决参数传递问题
def wrapper(*args,**kwargs):
startTime = datetime.now()
result = func(*args,**kwargs)
endTime = datetime.now()
print(endTime - startTime)
return result

# 返回原函数
return wrapper

类装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 检测数据,统一输出日志
def check_data(func):
def wrapper(self, *args):
data = response.json()
if item["category"] == "股权质押":
data = data["list"]

if not data:
self.logger.info(
f"{item['company']} {item['url']} 暂无 {item['category']}"
)
return
return func(self, *args)

return wrapper

钻石继承:(多继承问题)

​ a
/
b c
\ /
​ d
python 使用 MRO顺序 来解决 方法被重复调用的问题 详见

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class human:
def __init__(self):
self.name = ""
self.age = ""
self.gender = ""

def show_name(self, name):
print(name)

def show_age(self, age):
print(age)

def show_gender(self, gender):
print(gender)

def show_info(self):
print(self.name, self.age, self.gender)


class cxs(human):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.name = "cxs"
self.age = "24"
self.gender = "man"


c = cxs()
c.show_name("cxs")
c.show_age("24")
c.show_gender("man")
c.show_info()

OS 模块操作文件

对于任何的文件名的操作,你都应该使用 os.path 模块,而不是使用标准字符串操作来构造自己的代码。

遍历文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 所有文件夹的完整路径
In [45]: [root for root, folders, files in os.walk(folder)]
Out[45]:
['C:\\Users\\chen_xiaosheng\\Desktop\\hello-world\\glidedsky全部关卡',
'C:\\Users\\chen_xiaosheng\\Desktop\\hello-world\\glidedsky全部关卡\\test1',
'C:\\Users\\chen_xiaosheng\\Desktop\\hello-world\\glidedsky全部关卡\\test2',
'C:\\Users\\chen_xiaosheng\\Desktop\\hello-world\\glidedsky全部关卡\\雪碧图2']


# 递归获取所有文件夹
# [], [], [] 分别对应 'test1', 'test2', '雪碧图2' 三个文件夹内部
In [46]: [folders for root, folders, files in os.walk(folder)]
Out[46]: [['test1', 'test2', '雪碧图2'], [], [], []]


# 递归获取所有文件名
In [52]: [files for root, folders, files in os.walk(folder)]
Out[52]:
[['base_img.py',
'glided.html',
'glidedsky-capture.py',
'glidedsky.html',
'ip代理.py',
'屏幕坐标定位.exe',
'雪碧图.png',
'雪碧图.py'],
[],
[],
['baidu_nums.py',
'glided_screenshot.py',
'image_model.h5',
'img_api.py',
'num_recog.py',
'sprite_data.json',
'tencentAI.py',
'雪碧图-2.py']]

获取所有文件名

1
2
3
4
5
6
7
8
In [2]: dir_path = "C:/Windows/System32/winevt/Logs"
In [3]: os.listdir(dir_path)
Out[3]:
['AirSpaceChannel.etl',
'Application.evtx',
'HardwareEvents.evtx',
'Hewlett-Packard.evtx',
'Internet Explorer.evtx']

文件重命名

1
os.rename(old_name, new_name)

获取扩展类型

1
2
In [9]: os.path.splitext('Blasphemous.exe')
Out[9]: ('Blasphemous', '.exe')

获取文件大小(字节)

1
2
3
In [5]: file_path = "C:\\Users\\Desktop\\hello-world\\utils.py"
In [6]: os.path.getsize(file_path)
Out[6]: 1142

删除文件

1
2
In [7]: file_path = "C:\\Users\\Desktop\\hello-world\\清空日志.py"
In [8]: os.remove(file_path)

判断文件 or 文件夹(文件必须真实存在)

1
2
3
4
5
6
7
In [10]: file_path = "C:\\Users\\Desktop\\hello-world\\utils.py"
In [11]: os.path.isfile(file_path)
Out[11]: True

In [12]: dir_path = "C:\\Users\\Desktop\\hello-world"
In [13]: os.path.isdir(dir_path)
Out[13]: True

获取当前目录

1
2
3
4
5
6
7
8
9
10
11
12
In [2]: os.getcwd()
Out[2]: 'D:\\python\\Scripts'

print(__file__)
print(os.getcwd())
print(os.path.dirname(__file__))

"""
C:\Users\new-hello-world\ipython脚本测试\path_test.py
C:\Users\new-hello-world\ipython脚本测试
C:\Users\new-hello-world\ipython脚本测试
"""

获取父级目录

1
2
3
4
5
6
In [3]: os.path.dirname(os.getcwd())
Out[3]: 'D:\\python'

p1 = os.path.abspath("../..") # 父父父级
p2 = os.path.abspath("..") # 父父级
p3 = os.path.abspath(".") # 父级

路径合并

1
2
3
4
5
6
In [26]: d1 = "C:\\Users\\new-hello-world\\ipython脚本测试"
In [32]: d2 = "cxs"
In [30]: d3 = "cxs.png"

In [33]: os.path.join(d1, d2, d3)
Out[33]: 'C:\\Users\\new-hello-world\\ipython脚本测试\\cxs\\cxs.png'

创建文件夹

1
os.mkdir(folder)

文件移动

1
shutil.move(old_src, new_src)

获取计算机名

1
os.popen("hostname").read()

time.perf_counter(计算秒数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import time

def main():
time.sleep(1)
a = time.perf_counter()
print(a)
time.sleep(1)
b = time.perf_counter()
print(b)

'''
输出:(时间从b)
209.6693149
210.6700619
'''

windows消息弹窗

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'''
pip install pywin32
'''
import win32api, win32con

# 程序会自动暂停,直到按确认
win32api.MessageBox(0, "提醒OK消息框", "提醒", win32con.MB_OK)
win32api.MessageBox(0, "是否信息框", "提醒", win32con.MB_YESNO)
win32api.MessageBox(0, "说明信息框", "提醒", win32con.MB_HELP)
win32api.MessageBox(0, "警告信息框", "提醒", win32con.MB_ICONWARNING)
win32api.MessageBox(0, "疑问信息框", "提醒", win32con.MB_ICONQUESTION)
win32api.MessageBox(0, "提示信息框", "提醒", win32con.MB_ICONASTERISK)
win32api.MessageBox(0, "确认信息框", "提醒", win32con.MB_OKCANCEL)
win32api.MessageBox(0, "重试信息框", "提醒", win32con.MB_RETRYCANCEL)
win32api.MessageBox(0, "是否取消信息框", "提醒", win32con.MB_YESNOCANCEL)

# 窗口最顶层
win32api.MessageBox(0, msg, "涨停板开啦 ↑↑↑↑↑↑", win32con.MB_TOPMOST)

merry异常处理(https://zhuanlan.zhihu.com/p/390111195)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from merry import Merry

merry = Merry()
merry.logger.disabled = True

@merry._try
def process(num1, num2, file):
result = num1 / num2
with open(file, 'w', encoding='utf-8') as f:
f.write(str(result))

@merry._except(ZeroDivisionError)
def process_zero_division_error(e):
print('zero_division_error', e)

@merry._except(FileNotFoundError)
def process_file_not_found_error(e):
print('file_not_found_error', e)

@merry._except(Exception)
def process_exception(e):
print('exception', type(e), e)

上述代码作用相当于:

1
2
3
4
5
6
7
8
9
10
11
12
13
def example(num1, num2, path):
try:
result = num1 / num2
with open(path, 'r') as file:
file.read()
except ZeroDivisionError:
print("num2 cannot be zero!")
except TypeError:
print("num1 and num2 should be number!")
except FileNotFoundError:
print(f"file {path} not found!")
except Exception as e:
print(f'exception information: {e.args}')

不过多了几个优点:

  • 可复用
  • 逻辑代码模块异常处理模块分离

lambda用法:

冒号左边是参数,可以有多个,用逗号隔开

冒号右边为表达式,lambda 返回值是一个函数的地址,也就是函数对象

配合其他函数:

  • filter,用于过滤列表元素

    1
    2
    In [4]: list(filter(lambda x: x % 3 == 0, [1, 2, 3]))
    Out[5]: [3]
  • sorted,用于排序列表元素

    1
    2
    3
    # 按照元素与5距离从小到大进行排序
    In [6]: sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x))
    Out[6]: [5, 4, 6, 3, 7, 2, 8, 1, 9]
  • map,把操作映射到列表的每个元素

    1
    2
    In [8]: list(map(lambda x: x+1, [1, 2,3]))
    Out[8]: [2, 3, 4]
  • reduce,用于指定列表中两两相邻元素的结合条件

    注意最后只返回一个结果

    1
    2
    3
    In [12]: lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    In [13]: reduce(lambda a, b: '{}, {}'.format(a, b), lst)
    Out[13]: '1, 2, 3, 4, 5, 6, 7, 8, 9'

mimetypes 获取 content-type

1
2
3
4
In [26]: from mimetypes import types_map
In [32]: types_map['.png']

Out[32]: 'image/png'

muggle_ocr 文字识别

1
2
3
4
5
6
7
8
9
10
import muggle_ocr


def muggle_captcha(img: bytes):
"""
验证码识别
"""
sdk = muggle_ocr.SDK(model_type=muggle_ocr.ModelType.Captcha)
result = sdk.predict(image_bytes=img)
return result

关闭requests警告

1
urllib3.disable_warnings()

汉字转拼音(pypinyin)

https://pypinyin.readthedocs.io/zh_CN/master/

1
2
3
4
5
6
7
8
9
10
11
In [10]: from pypinyin import pinyin, Style

In [12]: s = "拜尔3434kdjfkj"

In [13]: pinyin(s, style=Style.FIRST_LETTER)
Out[13]: [['b'], ['e'], ['3434kdjfkj']]

In [14]: result = pinyin(s, style=Style.FIRST_LETTER)

In [15]: "".join(l[0] for l in result)
Out[15]: 'be3434kdjfkj'

tenacity重试

1
2
3
4
5
@tenacity.retry(
reraise=True, # 达到最大重试次数,重新抛出异常
stop=stop_after_attempt(3), # 重试次数
wait=wait_fixed(1) # 时间间隔
)

安装Crypto加密模块

1
2
3
pip uninstall crypto
pip uninstall pycryptodome
pip install pycryptodome