0%

Python小技巧

安装指定版本的第三方库

1
pip install robotframework==2.8.7

要用pip安装指定版本的Python包,只需通过==操作符指定即可。

将当前虚拟环境中的依赖包以版本号生成至文件中【导出第三方库】:

1
pip freeze > requirements.txt

在指定位置安装第三方

1
pip install -t /Users/taoyi/.pyenv/versions/2.7.14/lib/python2.7/site-packages lxml

pip安装的包不一定是用户想要的位置,此时可以用-t选项来指定位置。

通过requirement.txt文件来管理pip的第三方库

文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
robotframework==3.0.2
robotframework-ride==1.5.2
robotframework-appiumlibrary==1.4.6
robotframework-DatabaseLibrary==1.0.1
robotframework-Selenium2Library==3.0.0
robotframework-requests==0.4.7
robotframework-sshlibrary==2.1.3
robotframework-HttpLibrary==0.4.2
requests==2.18.4
PyMySQL==0.8.0
MySQL-python==1.2.5

然后通过以下命令来批量安装第三方库

1
pip install -r requirement.txt

查看有更新的pip第三方库

1
2
3
4
5
6
7
# taoyi @ TaoYi-Mac in ~ [16:27:56]
$ pip list --outdate --trusted-host pypi.douban.com
Package Version Latest Type
------------------------- ------- ------- -----
robotframework-ride 1.5.2 1.5.2.1 sdist
robotframework-sshlibrary 2.1.3 3.0.0 sdist
setuptools 28.8.0 39.1.0 wheel

更新指定的第三方库

1
pip install --upgrade robotframework-sshlibrary

查看第三方库的详细信息

1
pip show robotframework-sshlibrary

pip配置文件更新

pip配置文件是~/.pip/pip.conf文件

1
2
3
4
5
6
7
8
9
10
11
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/

[global] # 设置pip的全局的源
index-url = http://pypi.douban.com/simple

[install] # pip install指定的安装源
trusted-host=pypi.douban.com

[list] # pip list命令接口的展示方式设置
format=columns

end是print()函数的一个参数。end 是输出语句结束以后附加的字符串,它的默认值是换行(’\n’)。

1
2
3
4
5
print('')#end值为默认值(换行\n)
print('*',end = ' ') # end值为空格
print('*',end = '') # 默认为末尾换行/n,end=''末尾为空所以不换行
print('*',end = '1') # end值为字符串‘1’
print('*',end = '12') # end值为字符串‘12’

打印中的赋值语句

1
2
print ('%d * %d = %d' %(i, j, i * j), end='\t')
# 三个%d分别从后面跟着的3个参数取对应的值

VSCode的代码段设置

1
2
3
4
5
6
7
8
9
10
{
"MarkDown insert Pyhton": {
"prefix": "MDP",
"body": [
"```python\n\n\n```",
"$2"
],
"description": "MarkDown insert Pyhton"
}
}

共享本地文件给局域网访问

1
python -m http.server

共享当前运行该命令的本地目录,给予在局域网内访问;默认共享端口为8000,即访问地址为:localhost:8000

字典在for循环中数据覆盖的分析与解决

预期打印出来的list为:[{‘num’: 0}, {‘num’: 1}, {‘num’: 2}],结果为[{‘num’: 2}, {‘num’: 2}, {‘num’: 2}]

1
2
3
4
5
6
lists=[]
dictionary={"num":""}
for i in range(3):
dictionary["num"]=i
lists.append(dictionary)
print(lists) #[{'num': 2}, {'num': 2}, {'num': 2}]

解决:将字典写在for循环中,得到预期的list[{‘num’: 0}, {‘num’: 1}, {‘num’: 2}]

1
2
3
4
5
6
lists=[]
for i in range(3):
dictionary = {"num": ""}
dictionary["num"]=i
lists.append(dictionary)
print(lists) #[{'num': 0}, {'num': 1}, {'num': 2}]

原因分析:

1. dictionary(字典)赋给list的是一个位置
2. dictionary定义在循环外,每次使用list.append(dictionary)赋给 list的都是相同的位置,即指向了同一块的地址;当在同一地址的dictionary的值已经改变了,所以list取到的之前位置的值改变了,表现出后面数据覆盖前面数据的表象
3. dictionary定义在循环内,相当于每一次循环生成一个dictionary,占用不同的位置存储值,所以可以赋给list不同元素不同的位置,获得不同的值。 

总结:

1. 对于不能理解地址,可以通过在循环中print(id(dictionary)),将地址打印出来对比分析
2. 在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用
3. 关于Python中复制、浅拷贝和深拷贝的区别
  - 直接赋值,传递对象的引用而已,原始列表改变,被赋值的b也会做相同的改变
  - copy浅拷贝,只拷贝父对象,不会拷贝对象的内部的子对象,所以原始数据改变,子对象会改变
  - copy深拷贝,包含对象里面的自对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变

全局变量和局部变量

1
2
3
4
5
6
7
def test():
if value == 1:
a += 1
return a

value = a = 1
b = test()

执行上述代码就会出现UnboundLocalError: local variable 'a' referenced before assignment这个报错。
因为在函数内部对变量赋值进行修改后,该变量就会被Python解释器认为是局部变量而非全局变量,当程序执行到a+=1的时候,因为这条语句是给a赋值,所以a成为了局部变量,那么在执行return a(或是print a)的时候,因为a这个局部变量还没有定义,自然就会抛出这样的错误。

解决方案一:
当全局变量。就是使用global关键字,在函数内部先声明a这个变量是全局变量。代码如下:

1
2
3
4
5
6
7
8
def test():
global a
if value == 1:
a += 1
return a

value = a = 1
b = test()

这时,a就成为了全局变量,在函数内部修改该变量,也就没有问题了。
这种情况外面的a执行完函数是2,而函数返回的也是2。

解决方案二:
当局部变量。就是这个变量只在函数内使用,那么只要在函数内把这个变量定义一下就行了。代码如下:

1
2
3
4
5
6
7
8
def test():
a = 1
if value == 1:
a += 1
return a

value = a = 1
b = test()

这种情况外面的a执行完函数还是1,而函数返回的则是2。

requests.post使用

  1. 带数据『data』的post

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # -*- coding:utf-8 -*-
    import requests
    import json

    host = "http://httpbin.org/"
    endpoint = "post"
    url = ''.join([host,endpoint])
    data = {'key1':'value1','key2':'value2'}

    r = requests.post(url,data=data)
    #response = r.json()
    print (r.text)
  2. 带header的post

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # -*- coding:utf-8 -*-
    import requests
    import json

    host = "http://httpbin.org/"
    endpoint = "post"

    url = ''.join([host,endpoint])
    headers = {"User-Agent":"test request headers"}

    # r = requests.post(url)
    r = requests.post(url,headers=headers)
    #response = r.json()
  3. 带json的post

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # -*- coding:utf-8 -*-
    import requests
    import json

    host = "http://httpbin.org/"
    endpoint = "post"

    url = ''.join([host,endpoint])
    data = {
    "sites": [
    { "name":"test" , "url":"www.test.com" },
    { "name":"google" , "url":"www.google.com" },
    { "name":"weibo" , "url":"www.weibo.com" }
    ]
    }

    r = requests.post(url,json=data)
    # r = requests.post(url,data=json.dumps(data))
    response = r.json()
  4. 带参数『params』的post

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # -*- coding:utf-8 -*-
    import requests
    import json

    host = "http://httpbin.org/"
    endpoint = "post"

    url = ''.join([host,endpoint])
    params = {'key1':'params1','key2':'params2'}

    # r = requests.post(url)
    r = requests.post(url,params=params)
    #response = r.json()
    print (r.text)
  5. 普通文件上传

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # -*- coding:utf-8 -*-
    import requests
    import json

    host = "http://httpbin.org/"
    endpoint = "post"

    url = ''.join([host,endpoint])
    #普通上传
    files = {
    'file':open('test.txt','rb')
    }

    r = requests.post(url,files=files)
    print (r.text)
  6. 定制化文件上传

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # -*- coding:utf-8 -*-
    import requests
    import json

    host = "http://httpbin.org/"
    endpoint = "post"

    url = ''.join([host,endpoint])
    #自定义文件名,文件类型、请求头
    files = {
    'file':('test.png',open('test.png','rb'),'image/png')
    }

    r = requests.post(url,files=files)
    print (r.text)
  7. 多文件上传

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # -*- coding:utf-8 -*-
    import requests
    import json

    host = "http://httpbin.org/"
    endpoint = "post"

    url = ''.join([host,endpoint])
    #多文件上传
    files = [
    ('file1',('test.txt',open('test.txt', 'rb'))),
    ('file2', ('test.png', open('test.png', 'rb')))
    ]

    r = requests.post(url,files=files)
    print (r.text)
  8. 流式上传

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # -*- coding:utf-8 -*-
    import requests
    import json

    host = "http://httpbin.org/"
    endpoint = "post"

    url = ''.join([host,endpoint])

    #流式上传
    with open( 'test.txt' ) as f:
    r = requests.post(url,data = f)

    print (r.text)

递归函数的使用

递归从入门到精通

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# sd_list = [{"scenes_id": "1", "scenes_data_ids": [5, 6, [{"scenes_id": "3", "scenes_data_ids": [56, 2, 24, 4]}]]}]
# 递归获取场景中的所有场景数据,并返回数据集合的list

def get_scenesDataId_list(sd_list):
# 初始变量定义在此,解决二次调用时,带入一次递归时的数据的问题
sd_new_list = []
if sd_list[0]['scenes_data_ids']:
num_list = sd_list[0]['scenes_data_ids']
for i in num_list:
if isinstance(i, int):
sd_new_list.append(i)
else:
sd_new_list += get_scenesDataId_list(i)
return sd_new_list

远程连接服务器执行shell命令及脚本

1
2
3
4
5
6
7
8
9
import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='172.18.71.199', port=22, username='dasouche', password='V4HubdvgBePJ')
stdin,stdout,stderr = ssh.exec_command("ls -l")
stdin,stdout,stderr = ssh.exec_command("./test.sh")
stdin,stdout,stderr = ssh.exec_command("python ./test.py")
print(stdout.read())

生成指定位数的小写字母和数字的随机数

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

def getRandomSet(bits):
num_set = [chr(i) for i in range(48, 58)]
char_set = [chr(i) for i in range(97, 123)]
total_set = num_set + char_set

value_set = ''.join(random.sample(total_set, bits))

return value_set

反转list的三种方法

  1. 使用reversed()函数
    1
    2
    3
    a=[1,2,3,4,5,6,7,8,9]  
    b=list(reversed(a))
    print b
    注意:reversed()函数返回的是一个迭代器,而不是一个List,需要再使用List函数转换一下。
  2. 使用sorted()
    1
    2
    3
    a=[1,2,3,4,5,6,7,8,9]  
    c=sorted(a,cmp=None, key=None, reverse=True)
    print c
    注意:其中reverse=True是按降序排列,reverse=False是按照升序排列。
  3. 使用分片
    1
    2
    3
    a=[1,2,3,4,5,6,7,8,9]  
    d=a[::-1]
    print d
    注意:其中[::-1]代表从后向前取值,每次步进值为1。