Python笔记

一、pip相关

pip 是 Python 包管理工具,该工具提供了对Python 包的查找、下载、安装、卸载的功能。

Ubuntu安装pip

sudo apt install python-pip
sudo apt install python3-pip

查看pip是pip2还是pip3

pip -V

Ubuntu升级pip

pip install --upgrade pip    # python2.x
pip3 install --upgrade pip   # python3.x

搜索包

pip search SomePackage

安装包

pip install SomePackage              # 最新版本
pip install SomePackage==1.0.4       # 指定版本
pip install 'SomePackage>=1.0.4'     # 最小版本
# 如果 Python2 和 Python3 同时有 pip,则使用方法如下:
python2 -m pip install SomePackage
python3 -m pip install SomePackage

升级包

pip install --upgrade SomePackage # 升级指定的包,通过使用==, >=, <=, >, < 来指定一个版本号。

卸载包

pip uninstall SomePackage

列出已安装的包:

pip list # 得看pip是pip2还是pip3
python2 -m pip list # 查看python2的pip安装的包
python3 -m pip list # 查看python3 的pip安装的包

显示安装包信息

pip show SomePackage

 __init__.py

__str__

使用print输出对象的时候,只要对象定义了__str__(self)方法,那么就会打印从在这个方法中return的数据,__str__方法需要返回一个字符串,当做这个对象的描写。

__dict__

对象的__dict__中存储了一些self.xxx的一些东西。

@property

@property是python的一种装饰器,是用来修饰方法的。加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。


class 

class Job:
  def __init__(self):
    self job_name = None

class Person:
  def __init__(self, name=unknow):
    self.name = name
    self.age = None
    self.hobby = {}
    self.set_hobby()
    self.job = Job()
  def set_hobby(self):
    self.hobby = {'swimming', 'basketball'}
  def __str__(self):
    return str(self.__dict__)
  @property
  def AGE(self):
    return self.age

p = Person('alan')
print(p)
print(p.AGE) # 用户进行属性调用的时候,直接调用AGE即可,而不用知道属性名age,因此用户无法更改属性,从而保护了类的属性。

二、python相关

基础语法

if 'a' in ('a', 'b'):
if 'a' in ['a', 'b']:

s='a,1,b,2,c,3'
items = s.split(',') # 默认按空格分 s.split('a,')
l = items[:-1]
for i in range(len(items)): # begin 0, range返回一个list
  if items[i].isdigit():
    print(int(items[i]))
  else:
    print(items[i])

s = set(['a', 'b'])
s = set(s.split(','))
if 'a' in s and 'A' not in s:
elif xxx:
elif xxx:
else:

c = True
flag = 'true' if c else 'false'

if not name
if name and not age:
if not age or name:
if key != 'a':
if key == 'a':
if '.txt' in file_name and count > 0:

s='alan'
if 'a' in s:

for item in items:
a = 'b' if True else 'c'

L = []
L.append('a')
L.append({'key1': value1, 'key2': value2})
L[-1]['key2']=value3

L1 = [123, 'xyz']
L2 = [2020, 'alan']
L1.extend(L2)
print(len(L))

l=['%d %d' % (i, i+1) for i in range(2, 5)] # ['2 3', '3 4', '4 5']
dd = {k: d[k] for k in d if 'txt' in k}
ll = [d[k] for k in d if 'txt' in k]
['%s %d' % (person['name'], person['age']) for person in persons]

# strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。

s = None
str = '-'
seq = ("a", "b", "c")
print(str.join(seq))

d=dict()
d['key1']=1
d['key2']=2
key1 = {'key1': 1, 'key2':2}['key1']
key1 = d.get('key1', 0)
print(d) # {'key2': 2, 'key1': 1}
l = list(d.keys())
print(d.keys()) # ['key2', 'key1']
print(d.items()) # [('key2', 2), ('key1', 1)]
l=sorted(d.items(),key=lambda x: x[1])
print(l) # [('key1', 1), ('key2', 2)]
l2=[[x[0]] for x in l]
print(l2) # [['key1'], ['key2']]
d.update({'key1': 9, 'key2': 5})
print(d) # {'key2': 5, 'key1': 9}

seq = ['one', 'two', 'three']
a=seq.pop(-2)
for idx, element in enumerate(seq):
  d.update({idx: element})
print(d)

a=min(0,1)
b=max([0,1])

while True:

l[0]
l[-1]
l[:3]
l[3:]
l[:-3]
l[-3:]
l[0:10:2]

[f(x) for x in l]
[float(x) for x in l]
print(%s --> %s % (str1, str2))

print(3/2) # python2为1,python3为1.5
print(3//2) # 1

s='Alan_001'
s=s.replace('_', '-').lower() # alan-001 # s.upper()

def f(args, b=''):
  import logging
  from datetime import datetime
  def f2():
    return None

NUM = {
    '1': 'one',
    '2': 'two',
}

a {
  'b':c,
  'd':e,
}
for key in a:
  print(key) # b, d

city_name = '%s_china' % city

a = ['a', 'b', 'c']
print('choose from: %s' % a)

a, b = ['1'], ['2']
text='hello,\
      alan'

s = str('hello') + (' alan' if True else '')

float(1)

# string->int
a = '10'
int(a) # 十进制string转化为int, 10
int(a, 16) #十六进制string转化为int,16

# int->string
a = 10
str(a) # int转化为十进制string
hex(a) # int转化为十六进制string

print('%#x'% 255) # 0xff

x ** 2 # 平方

return d[a] if a in d else a
a += '.%s' % b

ss = 'abc'
if str('a') in str(ss)
s.rstrip('/') # 删除string字符串末尾的指定字符(默认为空格)
s.lstrip('/') # 删除string字符串前面的指定字符
path = 's3://{}/{}'.format('bucket_name', 'file_name')
if s.endswith('.txt'):

s="abcd"
s = s[s.index("bc") + len("bc"):]
L=[3,4,5,6]
for i in L:
  print('[%s/%s]: %s' % (L.index(i)+1, len(L), i))

print("%d person%s" % (num, 's' if num > 1 else ''))

[{'Id': idx,'message': message} for idx, message in enumerate(messages)] # enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标
l1, l2 = [], []

1. "%d" % i 表示直接输出 i 的结果
2. "%2d" % i 表示输出宽度为 2 的字符串,如果 i 的宽度不够 2,则右对齐
3. %02d" % i 表示输出宽度为 2 的字符创,如果 i 的宽度不够 2,则补0

t = float(format(timestamp, '.3f'))
%.1f


filter(函数,序列)函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
该函数接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
def is_odd(n):
    return n%2==1
newlist = filter(is_odd,[1,2,3,4,5,6,7,8,9,10])
newlist = list(filter(lambda n:n%2==1,[1,2,3,4,5,6,7,8,9,10]))
newlist = list(x for x in [1,2,3,4,5,6,7,8,9,10] if x%2==1)
newlist = [_ for _ in filter(lambda x: x, [1,2,3,4,5,6,7,8,9,10])]

del L[0] # 删除list元素

列表前面加星号作用是将列表中所有元素解开成独立的参数,传入函数,参数数量等于len(data)
字典前面加两个星号,是将字典解开成独立的元素作为形参。
def add(a, b):
    return a+b
data = [4,3] # data = (4,3)
print add(*data) # 7
data = {'a' : 4, 'b' : 3}
print add(**data) # 7

repr(object) 函数将对象转化为供解释器读取的形式,返回一个对象的 string 格式。
dict = {'runoob': 'runoob.com', 'google': 'google.com'};
repr(dict) # "{'google': 'google.com', 'runoob': 'runoob.com'}"

3.7//2 # 1.0 "/"表示浮点数除法,返回浮点结果;"//"表示整数除法。

L=[0]*5 # [0, 0, 0, 0, 0]
L=[[0]*5]*3 # [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
L[0][0]=1 # [[1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]]

abs(-1)
if any(char.isdigit() for char in word):
  continue

shebang

#!/usr/bin/env python3

在 Python 脚本的第一行经常见到这样的注释:
#!/usr/bin/env python3 或者 #!/usr/bin/python3 

在脚本中, 第一行以 #! 开头的代码, 在计算机行业中叫做 "shebang", 也叫做 sha-bang / hashbang / pound-bang / hash-pling, 其作用是"指定由哪个解释器来执行脚本", #!之后的空格是可选的, #!/usr/bin/env python3 和 #! /usr/bin/env python3 这两种写法都是允许的

  1. 用命令行执行脚本时, 指定解释器: python3 ./my_script.py;

  2. 也可以在脚本内, 通过 shebang 指定解释器. 比如想让 Python3 解释器来执行脚本, 那么, 在 Python 脚本的第一行写上 #!/usr/bin/python3 或者是 #!/usr/bin/env python3, 然后用命令行直接调用文件 -- ./my_script.py, shell 会检查脚本的第一行代码, 发现有 shebang, 会按其指定的解释器来执行; 大部分 Python 文件不必写 Shebang, 只有被直接执行的文件才有必要加入 Shebang

  3. 如果上面两种方式是冲突的, 比如在 shebang 中指定 python3, 但是命令行执行时指定 Python2 -- python2 ./my_script.py, 结果会如何? 结果是"命令行指定"比 "shebang 指定"更优先

  • #!/usr/bin/python3 表示 python3 解释器所处的绝对路径就是 /usr/bin/python3, 路径被写死了, 类似于编程中的"硬编码". 之所以有这种写法, 是因为在类 Unix 系统中, python 解释器一般情况下都位于这个路径, 如果碰到 python 解释器不在该路径下的话, 脚本就无法执行了!
  • #!/usr/bin/env/ python3 表示从 "PATH 环境变量"中查找 python3 解释器的位置, 路径没有被写死, 而是在"环境变量"中寻找 python3 解释器的安装路径, 再调用该路径下的解释器来执行脚本. 显然, 采用 #!/usr/bin/env python3 的写法更灵活更具有通用性, 推荐使用这种写法

 支持中文显示

#coding=utf-8

常见的写法有: #coding=utf-8 和 #! -*- coding:utf-8 -*-, 都是合法有效的但是, coding 和 =之间, 或者coding 和 :之间, 不能有空格! 

Python 2 默认使用的是 ASCII 编码 (不支持中文), Python 3 默认使用 UTF-8 编码 (万国码, 支持中文).所以 Python 2 中为了支持中文, 都会在开头加入 #coding=utf-8 这个声明来指定字符编码,而 Python 3 默认支持 UTF-8 编码, 不需要添加。

# -*- coding: UTF-8 -*-


导入模块

import os
import sys
import argparse
import logging
import coloredlogs
import termcolor
import yaml
import json
import simplejson
import time
from datetime import datetime
import getpass
import copy
import decimal
import hashlib
import re
import multiprocessing
import subprocess
import uuid
import requests
import urllib.request
from a.py import f1, f2

import math
import datetime
import calendar
import numpy as np
import pandas as pd
import traceback

 Most Popular Python Modules


注释

'''
Copyright (C) 2020 Alan Lan. All Rights Reserved.

learn python

usage:
python test.py a.txt b.txt -n alan -v
'''

"""learn python"""

# learn python

 主函数入口

def run():
  print("hello, alan")

if __name__ == '__main__':
  run()

os 模块

import os
file_path=os.path.expanduser("~") + '/test.json'
# folder, file_name = os.path.split(uri)
if os.path.splitext(uri)[-1] == '.json': #分离文件名[0]和后缀[-1]
if not os.path.exists(file_path):
    # os.makedirs(dir_path)
    raise Exception('not exist [%s]' % file_path)
if os.path.exists(file_path):
   os.remove(file_path)

root='/home'
dir=alan
file_name='test'
file_path = os.path.join(root,dir,'%s.txt' % file_name)
print(file_path)

os.getcwd()
abs_path=os.path.abspath(__file__)
real_path=os.path.realpath(__file__)
dir=os.path.dirname(real_path)
file_path=os.path.join(os.path.dirname(__file__), 'test.txt')
log_path = os.path.dirname(os.getcwd())

cmd='cd %s % os.path.dirname(os.path.realpath(__file__))'
os.system(cmd)
basename = os.path.basename(file_path) # xx.xx

if os.path.isfile(file_path):
  txt = open(file_path, 'r').read().strip()

txt_files = []
for (dirpath, dirnames, filenames) in os.walk(folder):
  for filename in filenames:
    if filename.endswith('.txt'):
      txt_files.append(os.path.join(dirpath, filename))

for file in os.listdir(directory):

linux中~表示"/home/user_name/"这个路径,但是python不认识~这个符号,需要用os.path.expanduser把~展开成"/home/user_name/"


sys 模块

import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + '/..') # 新添加的目录会优先于其他目录被import检查

argparse 模块(命令行参数解析)

ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][,metavar][, dest])

官方文档:argparse --- 命令行选项、参数和子命令解析器 — Python 3.10.0 文档

添加位置参数声明的参数名前缀不带-或--,按照顺序进行解析,在命令中必须出现,否则报错

添加可选参数声明的参数名前缀带-或--,前缀是-的为短参数,前缀是--是长参数,两者可以都有,也可以只有一个,短参数和长参数效果一样。可选参数的值接在位置参数的后面,不影响位置参数的解析顺序。

–name: 参数全名,需要加在参数上 如:python demo.py --name alan

-n: 参数简称,可与–name同时存在

name: 或者 dest=name:参数名,提供参数占位符,必须填写,否则报错。如:python demo.py alan

action: 参数的'store_true'指的是:触发action时为真,不触发则为假。即储存了一个bool变量,默认为false,触发不用赋值即变为true

type: 指定参数类型,默认是str,如果需要int,type=int即可

help: 指定参数的说明信息,可使用-h(–help)查看该信息

default: 提供参数默认值

choices: 参数的值只能在几个选项中选择

required: 默认情况下,可选项(前面有'-')被认为并不一定需要出现在命令行参数中,但是如果设置了required=True的话,则必须出现

nargs: 设置参数的个数,格式parser.add_argument('-name', nargs=x),x 的候选值以及含义如下:

含义
N参数的绝对个数(如:3)
‘?’0或1个参数
‘*’0或多个参数
‘+’1或者多个参数

test.py:

import argparse

  # 创建解析器对象
  parser = argparse.ArgumentParser(description='......')
  # 添加位置参数(positional arguments)
  parser.add_argument('hobby', help='your hobby', nargs='*')
  # parser.add_argument(dest='hobby', default='', help='bobby', nargs='*')
  # 添加可选参数(optional arguments)
  parser.add_argument('-a', dest='age', type=int, default=-1, help='your age')
  parser.add_argument('--j', dest='job', default='unknow', help='your job')
  parser.add_argument('-name', required=True, help='your name')
  parser.add_argument('-sex', required=True, choices=['male', 'female'])
  parser.add_argument('-v', dest='verbose', action='store_true', default=False, help='verbose') # action="store_false", default=True,
  # 解析参数
  args = parser.parse_args()

  hobby = ', '.join(args.hobby)
  print('name: %s' % args.name)
  print('sex: %s' % args.sex)
  print('age: %d' % args.age)
  print('hobby {}'.format(hobby))
  print('job: %s' % args.job)
  print('verbose: %s' % args.verbose)

  args.name = args.hobby[0]
  for hobby in args.hobby
    print(hobby)

if args.verbose:
  print()

 $ python3 test.py -h

positional arguments:
  hobby               your hobby

optional arguments:
  -h, --help          show this help message and exit
  -a AGE              your age
  --j JOB             your job
  -name NAME          your name
  -sex {male,female}
  -v                  verbose

$  python test.py -name alan -sex male

name: alan
sex: male
age: -1
hobby 
job: unknow
verbose: False

$  python test.py football swinning -name alan -sex male -a 18 --j engineer -v

name: alan
sex: male
age: 18
hobby football, swinning
job: engineer
verbose: True

logging 模块(日志输出)

级别排序:CRITICAL > ERROR > WARNING > INFO > DEBUG

默认生成的root logger的level是logging.WARNING,低于该级别的就不输出了

format常用格式说明
%(levelno)s: 打印日志级别的数值
%(levelname)s: 打印日志级别名称
%(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s: 打印当前执行程序名
%(funcName)s: 打印日志的当前函数
%(lineno)d: 打印日志的当前行号
%(asctime)s: 打印日志的时间
%(thread)d: 打印线程ID
%(threadName)s: 打印线程名称
%(process)d: 打印进程ID
%(message)s: 打印日志信息

test.py:(输出到控制台)

import logging

logging.basicConfig(format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)-8s: %(message)s', level=logging.INFO)  # 设置日志输出格式和级别
# fmt = '%(asctime)s [%(levelname)s] [%(module)s] - %(message)s'
# logging.basicConfig(format=fmt, datefmt='%m/%d/%Y %I:%M:%S')
# logger = logging.getLogger('ALAN_TEST')
# logger.setLevel(logging.INFO)

id = '001'
name = 'alan'
age = 20
# 将信息打印到控制台上
logging.debug("information")
logging.info('id: %s' % id)
logging.warning('name: %r' % name)
logging.error("age: %d" % age)
logging.critical(u"no job")

logging.info("id: {}".format(id))

$  python3 test.py

2020-06-01 17:07:32,001 - python_test.py[line:11] - INFO: id: 001
2020-06-01 17:07:32,001 - python_test.py[line:12] - WARNING: name: 'alan'
2020-06-01 17:07:32,001 - python_test.py[line:13] - ERROR: age: 20
2020-06-01 17:07:32,001 - python_test.py[line:14] - CRITICAL: no job

test.py:(输出到文件)

import logging

# 第一步,创建一个logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)  # log等级总开关
# 第二步,创建一个handler,用于写入日志文件
logfile = "/tmp/test.log"
fh = logging.FileHandler(logfile, mode='w')
fh.setLevel(logging.DEBUG)  # 输出到file的log等级的开关
# 第三步,定义handler的输出格式
formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
fh.setFormatter(formatter)
# 第四步,将logger添加到handler里面
logger.addHandler(fh)

logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
logging.critical("critical")

$ python3 test.py && cat /tmp/test.log

2020-06-01 17:30:05,690 - python_test.py[line:18] - INFO: info
2020-06-01 17:30:05,690 - python_test.py[line:19] - WARNING: warning
2020-06-01 17:30:05,690 - python_test.py[line:20] - ERROR: error
2020-06-01 17:30:05,690 - python_test.py[line:21] - CRITICAL: critical

coloredlogs 模块

import coloredlogs
import logging

coloredlogs.install(level=logging.DEBUG, fmt='%(asctime)s %(levelname)-8s %(message)s')

logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
logging.critical("critical")

 


termcolor 模块(改变控制台输出颜色)

支持下列的文字颜色:

grey, red, green, yellow, blue, magenta, cyan, white

支持下列的背景高亮:

on_grey, on_red, on_green, on_yellow, on_blue, on_magenta, on_cyan, on_white

linux支持下列属性:

bold, dark, underline, blink, reverse, concealed

import termcolor

text = "hello, world!"
print(termcolor.colored(str(text), 'green'))

text = termcolor.colored('Hello, World!', 'red', attrs=['reverse', 'bold', 'underline'])  
print(text)

raise Exception(termcolor.colored('hello %s' % name, 'red'))
logging.warn(termcolor.colored('file no exist', 'red'))
logging.info(termcolor.colored('json content:\n %s' % json.dumps(json_dir, indent=2), 'green'))
logging.info('today [%s] !' % termcolor.colored('%s-%s-%s' % (year, month, day), 'green'))

 


yaml 模块

import yaml

with open('/tmp/test.yaml', 'w') as y:
  yaml.safe_dump(dir_str, y, allow_unicode=False)

y = yaml.safe_load(dir_str)

y = yaml.load(dir_str, Loader=yaml.FullLoader)

json / simplejson 模块

import json
# json.dumps()用于将字典形式的数据转化为字符串,json.loads()用于将字符串形式的数据转化为字典
data = {
    'name' : 'alan',
    'sex' : 'boy',
    'age' : 20
}
print(data)
data1=json.dumps(data)
print(data1)
data2=json.loads(data1)
data3 = json.load(open("/tmp/a.json"))
data4 = json.dumps(a['b']['c'], indent=2, sort_keys=True)
print(data2)
print(type(data))
print(type(data1))
print(type(data2))
输出:
{'age': 20, 'name': 'alan', 'sex': 'boy'}
{"age": 20, "name": "alan", "sex": "boy"}
{'age': 20, 'name': 'alan', 'sex': 'boy'}
<class 'dict'>
<class 'str'>
<class 'dict'>

data1=json.dumps(data, indent=2) # json.dump(data, open("/tmp/out.json", 'w'), indent=2)
with open('test.json','a',encoding='utf-8') as f: 
    f.write(data1)
    f.close()
data3=json.load(open('test.json'))
print(data4)

file_path='/home/alan/test.json'
json_string = json.load(open(file_path))

d = dict()
with open(file_path, 'r') as f:
  d = json.load(f)

import simplejson
print(simplejson.dumps(data, indent=2))

with open('/tmp/test.json', 'w') as outfile:
  json.dump(dir_str, outfile)

time 模块

import time

t=str(time.time())
print(t) # 1604922487.35

t = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
print(t) # 2020-11-09 19:48:07

time.sleep(5) # 睡眠5s

datetime 模块

from datetime import datetime

now = datetime.today() # curr_time = datetime.today().strftime('%Y%m%d-%H%M%s')
t = '%d%02d%02d%02d%02d%02d' % (now.year, now.month, now.day, now.hour, now.minute, now.second)

now = datetime.now().strftime('%Y.%m.%d %H:%M:%S')
print('%d%02d%02d%02d%02d%02d' % (now.year, now.month, now.day, now.hour, now.minute, now.second))
t = datetime.fromtimestamp(1604482878).strftime('%Y-%m-%d')
print(t) # 2020-11-04

yesterday = datetime.fromtimestamp(time.time() - 24 * 3600).strftime('%Y.%m.%d')

getpass 模块(获取控制台输入)

import getpass

prompt_str = "Input your name: "
password = getpass.getpass(prompt=prompt_str)
print(password)

user = getpass.getuser() # 返回用户的登入名
a = raw_input("input:") # (python内置函数)将所有输入作为字符串看待,返回字符串类型

answer = input("Are you [%s] [yes/no]? " % name)
if answer == "yes":

copy 模块

import copy

origin = [1, 2, [3, 4]]
cop1 = copy.copy(origin)
cop2 = copy.deepcopy(origin)
print("equel" if cop1 == cop2 else "no same")
print("the same" if cop1 is cop2 else "no same")
origin[2][0] = "hey!" 
print(origin)
print(cop1)
print(cop2)

decimal 模块

当2个float类型数据,进行运算,就不能保证精度,导入 decimal模块,如果要不丢失精度Decimal类中必须要接收的是 str类型,如果还是传入 float类型,那么精度还是会丢失

import decimal

a = 0.1
b = 0.3
print(a)
print(b)
print(b-a)
print(decimal.Decimal(str(b)) - decimal.Decimal(str(a)))
print(decimal.Decimal(b) - decimal.Decimal(a))
if type(date) == 'Decimal'

hashlib 模块(加密)

import hashlib

text = "abc"

md5 = hashlib.md5()
md5.update(text.encode('utf-8')) # 注意转码
res = md5.hexdigest()
print("md5: %s" % res) # md5: 900150983cd24fb0d6963f7d28e17f72


sha256 = hashlib.sha256()
sha256.update(text.encode('utf-8'))
res = sha256.hexdigest()
print("sha256: %s" % res) # sha256: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

re 模块(正则表达式)

import re

text = '123-456-7890'

# re.match 只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None。
print(re.match(r"\d{2}", text).group(0)) # 12

# re.search 匹配整个字符串,直到找到一个匹配。
print(re.search(r"\d{2}", text).group(0)) # 12

# match 和 search 是匹配一次,findall 匹配所有, findall 返回列表。
print(re.findall("\d{2}", text)) # ['12', '45', '78', '90']

# compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
reg = re.compile('^\d+-\d{3}-\d{4,}$')
print(re.search(reg, text).group(0)) # 123-456-7890

# split 方法按照能够匹配的子串将字符串分割后返回列表。
print(re.split('-', text)) # ['123', '456', '7890']

match = re.findall(r'A-?\d+', "A-1")
s = match[0].replace('A-','').replace('A', '')

正则表达式模式

模式描述
^匹配字符串的开头
$匹配字符串的末尾。
.匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...]用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
[^...]不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re*匹配0个或多个的表达式。
re+匹配1个或多个的表达式。
re?匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{ n}精确匹配 n 个前面表达式。例如, o{2} 不能匹配 "Bob" 中的 "o",但是能匹配 "food" 中的两个 o。
re{ n,}匹配 n 个前面表达式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。"o{1,}" 等价于 "o+"。"o{0,}" 则等价于 "o*"。
re{ n, m}匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a| b匹配a或b
(re)对正则表达式分组并记住匹配的文本
(?imx)正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx)正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re)类似 (...), 但是不表示一个组
(?imx: re)在括号中使用i, m, 或 x 可选标志
(?-imx: re)在括号中不使用i, m, 或 x 可选标志
(?#...)注释.
(?= re)前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re)前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功
(?> re)匹配的独立模式,省去回溯。
\w匹配字母数字及下划线
\W匹配非字母数字及下划线
\s匹配任意空白字符,等价于 [ \t\n\r\f]。
\S匹配任意非空字符
\d匹配任意数字,等价于 [0-9].
\D匹配任意非数字
\A匹配字符串开始
\Z匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\z匹配字符串结束
\G匹配最后匹配完成的位置。
\b匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等.匹配一个换行符。匹配一个制表符。等
\1...\9匹配第n个分组的内容。
\10匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。

?直接跟随在子表达式后面,表示匹配前面的一次或者0次,类似于{0,1},如:abc(d)?可匹配abc和abcd

在Python的string前面加上‘r’, 是为了告诉编译器这个string是个raw string,不要转意。 例如,\n 在raw string中,是两个字符,\和n, 而不会转意为换行符。由于正则表达式和 \ 会有冲突,因此,当一个字符串使用了正则表达式后,最好在前面加上'r'。r必须紧贴着"写,中间不能有空格。

a = r"hello \n world"
a # 输出 'hello \\n world' #字符串前加r,实际存储的是\\n
print(a) # 输出 hello \n world

b = "hello \n world"
b # 输出 'hello \n world'
print(b) # 输出
hello
 world

# 用括号截取正则表达式的部分
str = '/tmp/2020-01-01/test.txt'
print(re.findall(r'/\d{4}-\d{2}-\d{2}/', str)[0]) # /2020-01-01/
print(re.findall(r'/(\d{4}-\d{2}-\d{2})/', str)[0]) # 2020-01-01

uuid 模块

import uuid

unique_code = str(uuid.uuid4())[:8]

$ MAC=$(python -c 'import uuid; print(uuid.uuid4().hex[:8])') # python -c 可以在命令行中执行 python 代码

pypcd 模块

# https://pypi.org/project/pypcd/
# pip install pypcd
# pip3 install --upgrade git+https://github.com/klintan/pypcd.git

from pypcd import pypcd

pc = pypcd.PointCloud.from_path(pcd_input_path)
# pnts = pypcd.PointCloud.from_path(pcd_input_path).pc_data
# pnts = [pc.pc_data[i] for i in xrange(0, len(pc.pc_data), 10)] 10倍降采样
points=[]
for i in range(len(pc.pc_data)):
  x = pc.pc_data[i]['x']
  y = pc.pc_data[i]['y']
  z = pc.pc_data[i]['z']
  points.append([x, y, z, 0])
result = np.array(points, pc.pc_data.dtype)
# dtype = [("x", np.float32),
#          ("y", np.float32),
#          ("z", np.float32)]
# result = np.array(points, dtype)
pc = pypcd.PointCloud.from_array(result)
pc.save_pcd(pcd_output_path)
# pc.save_pcd(pcd_output_path, compression='binary')

# pc = pypcd.make_xyz_point_cloud(np.array(points))
# dtype = pypcd._build_dtype(pc.get_metadata())
    def convert_pc_data(self, pc):
        if self.compressed_pcd:
            # _pc.type was ['I', 'I', 'I', 'U', 'U', 'U'], convert to
            # ['F', 'F', 'F', 'U', 'U', 'U']
            # _pc.size was [2, 2, 2, 1, 1, 1], convert to
            # [4, 4, 4, 1, 1, 1]
            pc.type[:3] = ['F'] * 3
            pc.size[:3] = [4] * 3

            dtype = pypcd._build_dtype(pc.get_metadata())
            pc.pc_data = pc.pc_data.astype(dtype)
            for i, k in enumerate(['x', 'y', 'z']):
                pc.pc_data[k] = pc.pc_data[k] / 100

multiprocessing 模块 (线程池&进程池)

""" python自带的线程池 """
from multiprocessing.pool import ThreadPool
import multiprocessing

def f(task, info):
  print(info)

hardware_concurrency = max(multiprocessing.cpu_count() - 1, 1)
thread_num = max(1, min(hardware_concurrency, len(tasks)))
pool = ThreadPool(processes=thread_num)
results = [pool.apply_async(
          func=f,
          args=(task, info)) for task in tasks]
pool.close() # 停止往线程池添加任务
pool.join() # 主线程等待子线程结束
# results = []
# for i in range(len(tasks)):
#   results.append(
#       pool.apply_async(func=f,
#                        args=(tasks[i], info)))
# pool.close()
# for result in results:
#   result.get()

from multiprocessing import Process
def print1(self):
  print('alan')
def print2(self):
  print('ayun')
def print(self):
  funcs = [print1, print2]
  p_list = []
  for func in funcs:
    p = Process(target=func)
    p.start()
    p_list.append(p)
  for p in p_list:
    p.join()

subprocess 模块

Python3中的subprocess.check_output函数可以执行一条sh命令,并返回命令的输出内容

import subprocess
  
def get_phabricator_diff_id():
  cmd = ["git", "log", "--name-status", "HEAD^..HEAD"]
  git_info = subprocess.check_output(cmd).strip()
  ret = [str(x.strip()) for x in git_info.split() if 'phabricator' in str(x)] # https://phabricator.xxx.com/D12345
  if not git_info or not ret:
    logging.warning('no git/phabricator info retrieved from current folder.')
    return None
  return ret[0].split('/')[-1].strip("'").strip() # D12345

requests 模块

import requests

url = "https://baidu.com/xx/xx/xx"
auth = ('alan', 'abcdefg')
res = requests.get(url, auth=auth)
text = res.text
content = json.loads(text)
if 'fields' in content:
   fields = content['fields']

urllib.request 模块

import urllib.request

url = "https://baidu.com/xx/xx/xx"
with urllib.request.urlopen(url) as stream:
  data = stream.read()
  encoding = stream.info().get_content_charset('utf-8')
  content = json.loads(data.decode(encoding))

 math模块

import math

math.ceil(3.1) # 向上取整
int(3.9) # 向下取整
round(3.5) # 四舍五入
round(56.659,1) # 56.7 后面1表示从小数点位数,默认0
(a, b) = math.modf(3.25) # 分别取整数部分和小数部分(0.25, 3.0)
radius = math.sqrt(x*x + y*y + z*z)

# 计算朝向
heading = math.atan2(2.0 * (qw * qz + qx * qy), 1.0 - 2.0 * (qy * qy + qz * qz))
heading = math.atan2(dy, dx)

random 模块

import random

rand_num = [random.randint(0, 255) for i in range(10)]

异常 

import traceback

try:
  #
  raise Exception('no exist file:\n%s' % file)
except Exception as e:
  print(e)

try:
  #
  raise RuntimeError("Failed to load map meta")
except:
  traceback.print_exc()

try:
  #
except AttributeError:
  #

try:
  #
except ValueError:
  #

写文件

lines = ['1', '2', '3']
with open(file_path, 'w') as fout:
  for l in lines:
    fout.write('%s\n' % l)
    # fout.write(l + "\n")
fout.close()
file = open(file_path, 'a')
file.write(name + '_' + str(time) + '\n')
file.close()

读文件

def read_file(file_path, content):
  with open(file_path, 'r') as lines:
    for l in lines:
      if l.strip() and not l.strip().startswith("#"):
        content.append(l.strip())
for line in open('/tmp/test.txt', 'r'): 
    a=line.split()
    l1.append(a[0])
    l2.append(int(a[1]))
    l3.append(float(a[2])/1000)

numpy模块

import math
import numpy as np

v1 = numpy.array([1,2,3])
m1 = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
v2 = numpy.dot(m1, v1)
v2_normalize = v2 / math.sqrt(v2[0] * v2[0] + v2[1] * v2[1] + v2[2] * v2[2])
cos_theta = numpy.dot(v2_normalize, (0, 1, 0))
angle_rad = numpy.arccos(cos_theta)
angle_degree = numpy.rad2deg(angle_rad)

numpy.nan
numpy.isnan()

pandas模块

import pandas as pd

data_df = pd.read_csv(path, sep=r'\s+', header=None)

求均值、方差、标准差、中位数

#coding=utf-8

import numpy as np

data = [1,2,3,4,9,10,5,6,7,8]

# 求均值
data_mean = np.mean(data)

# 求方差
data_var = np.var(data)

#求标准差
data_std = np.std(data,ddof=1)

#求中位数
#data.sort()
data = sorted(data)
size = len(data)
if size % 2 == 0:
    data_median = (data[size//2 - 1] + data[size//2])/2.0
else:
    data_median = data[size//2]

print("均值: %f" % data_mean)
print("方差: %f" % data_var)
print("标准差: %f" % data_std)
print("中位数: %f" % data_median)

画进度条 

def process_bar(percent, start_str=''):
    total_length = os.get_terminal_size().columns
    bar_length = total_length - 22
    grid = "\033[1;37;47m \033[0m"
    grid_num = int(percent * bar_length)
    bar = format('\r' + start_str + ''.join([grid] * grid_num), '*<{}'.format(
        bar_length + grid_num*len(grid) - grid_num)) + \
        '{:.1f}%|100%'.format(percent*100)
    print(bar, end='', flush=True)

for idx in range(100):
  percent = (idx + 1) / 100
  process_bar(percent, start_str='loading ')


欧拉角转旋转矩阵

参考:euler to rotation matrix python code example | Newbedev

import numpy as np

def euler_to_rotMat(yaw, pitch, roll):
    Rz_yaw = numpy.array([
        [numpy.cos(yaw), -numpy.sin(yaw), 0],
        [numpy.sin(yaw),  numpy.cos(yaw), 0],
        [0, 0, 1]])
    Ry_pitch = numpy.array([
        [numpy.cos(pitch), 0, numpy.sin(pitch)],
        [0, 1, 0],
        [-numpy.sin(pitch), 0, numpy.cos(pitch)]])
    Rx_roll = numpy.array([
        [1, 0, 0],
        [0, numpy.cos(roll), -numpy.sin(roll)],
        [0, numpy.sin(roll),  numpy.cos(roll)]])
    # R = RzRyRx
    rotMat = numpy.dot(Rz_yaw, numpy.dot(Ry_pitch, Rx_roll))
    return rotMat

四元素转欧拉角

import math

def euler_from_quaternion(x, y, z, w, degrees=False):
    """
    Convert a quaternion into euler angles (roll, pitch, yaw)
    roll is rotation around x in radians (counterclockwise)
    pitch is rotation around y in radians (counterclockwise)
    yaw is rotation around z in radians (counterclockwise)
    """
    t0 = +2.0 * (w * x + y * z)
    t1 = +1.0 - 2.0 * (x * x + y * y)
    roll_x = math.atan2(t0, t1)

    t2 = +2.0 * (w * y - z * x)
    t2 = +1.0 if t2 > +1.0 else t2
    t2 = -1.0 if t2 < -1.0 else t2
    pitch_y = math.asin(t2)

    t3 = +2.0 * (w * z + x * y)
    t4 = +1.0 - 2.0 * (y * y + z * z)
    yaw_z = math.atan2(t3, t4)
    if degrees:
        return math.degrees(roll_x), math.degrees(pitch_y), math.degrees(yaw_z)
    else:
        return roll_x, pitch_y, yaw_z

注意:

Python3.x中没有long类型,只有int类型

注释和import可写在函数里面

np.linalg.norm([dx,dy]) 

from tzlocal import get_localzone  # pip install tzlocal

timestamp = t.astimezone(get_localzone()).strftime('%s')

python -m pip install requests # python2通过pip安装了requests包
import requests # 报ImportError: No module named 'requests'
pip show requests # 找到request路径/usr/local/lib/python2.7/dist-packages
export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python2.7/dist-packages #将该路径加入PYTHONPATH中

TASK_NAME = os.getenv('TASK_NAME')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值