Category Archives: python

【3】Python之Click 库 命令行参数解析

Click是Flask的作者开发的一个第三方模块,用于快速创建命令行。它的作用与Python标准库argparse相同,但是使用更加简单。
click相对于argparse,就好比requests相对于urllib

Click使用分两步:
1)使用@click.command() 装饰一个函数,使之成为命令行接口;
2)使用@click.option() 等装饰函数,为其添加命令行选项等。

##Click 官方例子1
import click
@click.command()              //使函数hello成为命令行接口
@click.option('--count', defaut=1, help='Number of greetings.')
@click.option('--name', prompt='Your name', help='The person to greet.')
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    for x in range(count):
        click.echo('Hello %s! % name')

if __name__ == '__main__':
    hello()     
##option常用的设置参数
default: 设置命令行参数的默认值
help:    参数说明
type:    参数类型,可以是string, int, float等
prompt:  命令行提示信息,可输入参数
nargs:   指定命令行参数接受的值的个数
##Click 官方例子2
##通过nargs设定参数个数,type设置参数类型
@click.command()
@click.optoin('--pos', nargs=2, type=float)
def findme(pos):
    click.echo('%s / %s' % pos)

###
@click.command()
@click。option('--hash-type', type=click.Choice(['md5', 'sha1']))
def digest(hash_type):
    click.echo(has_type)

【2】python之ConfigParse配置文件解析

典型的配置文件包含一到多个章节(section),每个章节下可以包含一个到多个的选项(option)。如下就是一个典型的MySQL配置文件:

[client]
port           = 3306
user           = mysql
password       = mysql
host           = 127.0.0.1

[mysqld]
basedir            = /usr
datadir            = /var/lib/mysql
tmpdir             = /tmp
skip-external-locking

Python 标准库的configparser模块用以接卸配置文件。
ConfigParse模块包含一个ConfigParser类,一个ConfigParser对象,可同时解析多个配置文件。

import ConfigParser

##ConfigParser方法
###读取配置
sections           //返回一个包含所有章节的列表
has_section         //判断章节是否存在
items              // 元组的形式返回所有选项
options            // 返回一个包含章节下所有选项的列表
has_option         // 判断某个选项是否存在
get getboolean getint  getfloat   // 获取选项的值
###修改配置
remove_section      // 删除一个章节
add_section         // 添加一个章节
remote_option       // 删除一个选项
set                 // 添加一个选项
write               // 将ConfigParser对象中的数据保存到文件中

cf = ConfigParser.ConfigParser(allow_no_value=True)  //allow_no_value 默认为false,表示允许选项没有值,选项存在就表示取值为真,不存在取值为假
In [4]: cf.read('my.cnf')
Out[4]: ['my.cnf']

In [5]: cf.sections()
Out[5]: ['client', 'mysqld']

In [6]: cf.has_section('client')
Out[6]: True

In [7]: cf.options("client")
Out[7]: ['port', 'user', 'password', 'host']

In [8]: cf.has_option("client", "user")
Out[8]: True

In [9]: cf.get("client","host")
Out[9]: '127.0.0.1'

In [10]: cf.getint("client" ,"port")
Out[10]: 3306


In [11]: cf.remove_section('client')
Out[11]: True

In [12]: cf.add_section('mysql')

In [13]: cf.set('mysql','host','127.0.0.1')

In [14]: cf.set('mysql','port',3306)

In [15]: cf.write(open('my_copy.cnf', 'w'))

【1】python之操作 excel 库openpyxl 速查

import openpyxl
#打开文件
wb = oepnpyxl.load_workbook('example.xlsx')

#workbook
##workbook对象属性
wb.active    //获取活跃的worksheet
wb.read_only
wb.encoding
wb.properties  //文档元数据,如标题、创建者、创建日期
##workbook对象方法
wb.sheetnames //获取所有表格名称
ws = wb['sheetname']   //获取worksheet对象
wb.remove_sheet         //删除工作表
wb.create_sheet         //创建工作表
wb.copy_worksheet
wb.save('sample.xlsx')   //保存工作簿

#worksheet
##worksheet对象属性
ws.title       //表格标题
ws.dimensions //表格大小区域  ,A1:E11
ws.max_row     //最大行
ws.min_row     //最小行
ws.max_column   //最大列
ws.min_column   //最小列
ws.rows        //按行获取单元格(cell对象)
ws.columns     //按列获取单元格(cell对象)
ws.values       //按行获取表格内容
ws.freeze_panes  //冻结窗格,冻结第一行-A2;冻结第一列B1;冻结第一行列B2
##columns rows values 通过生成器返回数据
##worksheet对象方法
iter_rows        //按行获取所有单元格,可以指定起点、终点
list(ws.iter_rows(min_row=2, max_row=4, min_col=1, max_col=3))  //使用例子 
iter_columns
append           //在表格末尾加数据
merged_cell      //合并多个单元格
unmerged_cell    //移除合并的单元格

#Cell对象
ws['A2']   //cell对象
ws.cell(row=1, column=2)
##cell属性
row        //单元格所在行
column     //单元格所在列
cordinate  //单元格的坐标,行和列

##打印表格内容
###Example 1
for row in ws.values;
    print(*row)

###Example 2
for row in ws.rows:
    print(*[cell.value for cell in row])

###Example 3
for row in ws.iter_rows():
    print(*[cell.value for cell in row])

示例代码1

#!/usr/bin/python
#-*- coding: utf-8 -*-
import openpyxl

##计算表中学生的总成绩和平均成绩

def process_worksheet(sheet):
    avg_column = sheet.max_column + 1
    sum_column = sheet.max_column + 2

    for row in sheet.iter_rows(min_row=2, min_col=3):
        scores = [cell.value for cell in row]
        sum_scores = sum(scores)
        avg_scores = sum_scores / len(scores)

        #计算平均分和总分,并且保存到最后两列
        sheet.cell(row=row[0].row, column=avg_column).value = avg_scores
        sheet.cell(row=row[0].row, column=sum_column).value = sum_scores
    #设置平均分和总分的标题部分
    sheet.cell(row=1, column=avg_column).value = 'avg'
    sheet.cell(row=1, column=sum_column).value = 'sum'

def main():
    wb = openpyxl.load_workbook('example.xlsx')
    sheet = wb['student']
    process_worksheet(sheet)
    wb.save('example_copy.xlsx')

if __name__ == '__main__':
    main()

示例代码2

#!/usr/bin/python
#-*- coding: utf-8 -*-
import os 
import glob

import openpyxl

##合并多个excle到一个

def merge_xlsx_files(xlsx_files):
    wb = openpyxl.load_workbook(xlsx_files[0])
    ws = wb.active
    ws.title = "merged result"

    for filename in xlsx_files[1:]:
        workbook = openpyxl.load_workbook(filename)
        sheet = workbook.active
        for row in sheet.iter_rows(min_row=2):
            value = [cell.value for cell in row]
            ws.append(value)

    return wb

def get_all_xlsx_files(path):
    xlsx_files = glob.glob(os.path.join(path, '*.xlsx'))
    sorted(xlsx_files, key=str.lower)
    return xlsx_files

def main():
    xlsx_files = get_all_xlsx_files(os.path.expanduser('~lmx'))
    wb = merge_xlsx_files(xlsx_files)
    wb.save('merged_form.xlsx')

if __name__ == '__main__':
    main()

各种国内镜像加速(pip, docker, yum)

1、pip

Linux系统

mkdir ~/.pip
cat > ~/.pip/pip.conf << EOF
[global] 
trusted-host=mirrors.aliyun.com 
index-url=https://mirrors.aliyun.com/pypi/simple/
EOF

Windows系统

首先在window的文件夹窗口输入 : %APPDATA%然后创建pip文件夹最后创建pip.ini文件,写入如下内容:

[global] 
index-url = https://mirrors.aliyun.com/pypi/simple/ 
[install] 
trusted-host=mirrors.aliyun.com

2、docker

cat  > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://qntdeamw.mirror.aliyuncs.com"]
}
EOF

3、yum

#Centos7 (centos8貌似官方mirrors包含了国内镜像站,会根据本地IP就近选择国内mirros)
#用curl
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo  
#用wget 
wget http://mirrors.aliyun.com/repo/Centos-7.repo
wget http://mirrors.aliyun.com/repo/epel-7.repo
mv Centos-7.repo /etc/yum.repos.d/
mv epel-7.repo /etc/yum.repos.d

python 小功能

a = dist(25).zip
b = a.replace("(","").relpace(")","")
**************************************************************
import sys, os

#win环境判断传入参数是单文件名/带完整路径的文件名,并做处理
arg = sys.argv[1]
sourceDir = "d:\\tmp\\"

if arg.find("\\") > 0:
    packageName = os.path.basename(arg)
    sourceFile = arg
else:
    packageName = arg
    sourceFile = sourceDir + packageName
packageNewName = packageName.replace('(','').replace(')','')
sourceFile = sourceFile.replace("\\","\\\\")    
print(packageName, packageNewName)
print(sourceFile)

python 自动化运维–fabric库

1、windows拷贝文件到linux部署脚本(python)


# encoding='utf-8'

from fabric import Connection
import sys 

from fabric import Connection
import sys
packageName = sys.argv[1].replace('(','').replace(')','')
sourceDir = "C:\\tmp\\"
destDir = "/usr/local/src/"

with  Connection(host="122.226.107.154", port=2024, user="root", connect_kwargs={"password":"xxxx"}) as c:
    c.put(sourceDir + sys.argv[1], destDir + packageName)
    c.run('rm -rf /usr/local/src/dist')
    c.run('rm -rf /usr/local/app/szzj-portal-pc/*')
    c.run('unzip -o /usr/local/src/%s -d /usr/local/src/' %(packageName))
    c.run('/usr/bin/mv -f /usr/local/src/dist/* /usr/local/app/szzj-portal-pc/')

fabric 官网已经更新到2.6版,阿里镜像下载也已经是2.5的版本,但是网络上搜索到的案例大部分是按照1.X版本编写的。今天查看了下官网的文档,一些用法记录下。

2、基本上只要使用Connection这个api :

fabric.connection.Connection

这个类是从 Invoke 的Context 继承过来的,另外它还封装了Paramiko SSHClient 。可用参数如下:
Connection(hostuser=Noneport=Noneconfig=Nonegateway=Noneforward_agent=Noneconnect_timeout=Noneconnect_kwargs=Noneinline_ssh_env=None)

这里主要说明下connect_kwargs这个参数,它的值是字典(dict),比如密码,密钥key只能设置在这里。这个字典会直接传递给paramiko.client.SSHClient.connect解析,完整的可用字段如下:connect(hostnameport=22username=Nonepassword=Nonepkey=Nonekey_filename=Nonetimeout=Noneallow_agent=Truelook_for_keys=Truecompress=Falsesock=Nonegss_auth=Falsegss_kex=Falsegss_deleg_creds=Truegss_host=Nonebanner_timeout=Noneauth_timeout=Nonegss_trust_dns=Truepassphrase=Nonedisabled_algorithms=None)

3、另外是多主机的操作api

  1. fabric.group.Group(*hosts**kwargs) /**抽象类,无法直接使用,只能选用下面两个
  2. fabric.group.SerialGroup(*hosts**kwargs)
  3. fabric.group.ThreadingGroup(*hosts**kwargs)

因为本机测试不支持put (2.5版本)。group.py也看了,确实没有put ,不好用。
还是选择了for 循环IP列表调用Connection 来实现多主机操作。

其它

1、参数传递 :

python 的参数传递到 shell 脚本 c.run('/root/test.sh %s' %(sys.argv[1]))
实现上类是print函数传参。