版本管理 pipenv
先前的python 之版本控制 中介绍过pyenv和virtualenv,个人一直使用virtualenv,非常习惯和顺手。基本思路是需要使用某一版本的python解释器去官网上下载所需要版本,然后用virtualenv从该版本创建出所需的虚拟环境。所有的解释器都是笔者自己手动管理。而pipenv相当于集pyenv virtualenv于一身。完整信息参见pipenv官网。
安装pipenv
# mac下可以brew
brew install pipenv
# 直接pip安装,避免和系统默认产生冲突
pip install --user pipenv
# 可以在机器的 .bashrc 中配置补全功能
eval "$(pipenv --completion)"
笔者直接用brew安装的,结果引来了很多麻烦,后面详述。
与virtualenv 相比,pipenv会自动去解析你当前目录下的 Pipfile文件,由此去安装依赖,配置进而取代requirements.txt的管理。但是pipenv仍然需要用户去下载不同的python解释器,如果你指定一个你本地没有的解释器来创建虚拟环境则会报出:
Warning: Python 3.7 was not found on your system…
You can specify specific versions of Python with:
$ pipenv --python path/to/python
使用
Pipfile文件的格式在官网中详细给出了,此处简单示例:
[[source]]
url = "https://mirrors.aliyun.com/pypi/simple"
verify_ssl = true
name = "pypi"
[packages]
requests = "*"
[dev-packages]
django = "*"
[requires]
python_version = "3.6"
在本地测试目录下依次执行:
# 创建虚拟env环境类似 virtualenv -p python3.6
# 并且安装 Pipfile的包,并生成对应的Pipfile.lock文件
pipenv install
# 激活当前目录对应的env
pipenv shell
# 安装package到当前evn中,同时会更新Pipfile,Pipfile.lock
pipenv install your_package
# 导出所安装的package信息到requirements.txt中
pipenv lock -r > requirements.txt
# 回归系统环境,用deactive终端显示上退出,实际也是退出,但再次pipenv shell 会显示当前终端已经激活了虚拟环境
exit
其实如果virtualenv如果使用的比较熟练,可以不必转用pipenv。自己手动管理所有的解释环境,在哪里,用哪个,心里都非常清楚。pipenv默认是在user的home目录下的 .local文件中创建了虚拟env环境,就是让版本控制更便捷。
出现问题
OSError
pipenv install初始化创建虚拟环境时如果如果出现了OSError导致失败,多数是ReadTimeoutError,在初次创建虚拟环境时候会去files.pythonhosted.org下载安装pip,setuptools等,如果网络不好丢包比较严重就会超时报错。
自动升级
笔者是brew install pipenv的,结果默认下载了python3.6的解释器安装了,出现了一个问题是系统全局python默认还是2.7,但是默认的pip是3.x(因为笔者原本机器上有几个python3.x的版本,且映射了bin/ 到PATH中)。恢复过程很是难受,不过倒是发现很多以前忽略的东西:
MacOS下系统python所在路径
/System/Library/Frameworks/Python.framework/Versions/ 所以如果想要恢复,核心问题在找到默认pip是指向何处的,然后通过修改连接,PATH去改变pip的搜寻顺序。
Linux Tips
which & whereis
是否遇到过 which a 命令有输出,但是whereis a 没有输出?
which 是搜寻你的命令 a 使用的是PATH中那个一路径下的命令。
whereis则搜寻的是user.cs_path,可以用sysctl user.cs_path 查看,二者是不一样的
PATH
修改PATH是很多时候经常做的事,当时笔者安装过几个版本的python3.x后就把其下属的bin/映射到PATH里了,问题是,PATH是有序的。echo ${path/''/'\n'} 查看其中的顺序就是使用命令a 时的搜寻顺序,先到先用。所以即便多个目录下有 pip命令,当笔者把安装的python3.x的bin/接在PATH前时,就会把全局pip不小心改成了python3.x下的。
export PATH=/usr/local/bin:$PATH
export PATH=$PATH:/usr/local/bin
此二者是不一样的。
docker volume 相对路径
先前碰到一个compose文件,没有多看就启动了其中的 pg,其data是映射到我本地的,结果我想找其挂载地址发现用的是相对路径。之前习惯默认是指定绝对的宿主机挂载路径,结果用相对路径找不到了。
docker inspect container_name 查看处的路径是CentOS下docker的容器路径。MacOS下根本没有
可以用
docker volume 相关命令操作这种相对路径创建的挂载
docker volume ls 查看列表
docker volume rm volume_name 删除
sz & rz
这是两个好东西,多数同学平时远程拷贝文件估计与笔者相同,用scp。但是如果是跳板机器转过去的呢?如果跳了不止一次呢?慢慢用 scp一步一步导出。。。如果是一个大点的文件,传一次10分钟,多跳几次。。。。。。
改用 sz 和 rz 吧。直接就从本地上传到,或者下载了,连scp基础的那些输入项都免了。
具体的安装配置过程就不详述了,item2上怎么配置随处可找。
Python
python-jenkins
python操作Jenkins的包,参见官网说明 。接口倒是挺全的,有些地方用起来也不难,就是返回的数据没找到文档,Jenkins官方是否提供笔者没找到。只能参照界面显示去看,比较费时。
笔者最难以忍受的是:
def jenkins_request(self, req, add_crumb=True, resolve_auth=True):
try:
if resolve_auth:
self._maybe_add_auth()
if add_crumb:
self.maybe_add_crumb(req)
return self._response_handler(
self._request(req))
except req_exc.HTTPError as e:
# Jenkins's funky authentication means its nigh impossible to
# distinguish errors.
if e.response.status_code in [401, 403, 500]:
raise JenkinsException(
'Error in request. ' +
'Possibly authentication failed [%s]: %s' % (
e.response.status_code, e.response.reason)
)
elif e.response.status_code == 404:
raise NotFoundException('Requested item could not be found')
else:
raise
except req_exc.Timeout as e:
raise TimeoutException('Error in request: %s' % (e))
except URLError as e:
# python 2.6 compatibility to ensure same exception raised
# since URLError wraps a socket timeout on python 2.6.
if str(e.reason) == "timed out":
raise TimeoutException('Error in request: %s' % (e.reason))
raise JenkinsException('Error in request: %s' % (e.reason))
这里的 jenkins_request 是在执行 build_job操作时候,下两层调用的,也是这个包通用和jenkins交互的请求方法。这个方法里会抛出一个 Possibly authentication failed 异常。
这简直就是 坑爹到一定境地的做法。当时以为是在调用 build_job 构建时必须要传token,很多其他的地方对这个错也没详细说明。因为此前笔者测试调用build_job是成功的,但是后面死活不行,这种提示让笔者在用户认证这里转了n圈。
然后调试进入发现是上面抛出的,再看上面注释发发现这种异常是因为Jenkins's funky authentication means its nigh impossible to distinguish errors. 发生了一个不能辨别的错误。后面解决问题的方式是,从之前构建成功的构建中拉出信息对比,发现一个参数传入的不合法最后才发现是一个不合法额参数造成。
这里提供一种思路,往后如果碰到一个地方执行成功,而后不成功,不妨把成功的快照数据拉出来仔细对比,说不定就查处了问题
此外还有可能引发上述报错的是 create_job 指定的config_xml必须是 utf-8编码,否则也是上面额错误。总之,上述错误要依据具体调用方法查找,多数是参数引起的。
python-gitlab
python用以和gitlab交互的bao。首先gitlab官方给出了API文档 其中的说明非常详尽。
使用包的说明文档 也非常详尽。
例如Porject相关接口
projects = gl.projects.list()
只给出了几个参数,作为过滤条件,实际上,project是objects.ProjectManager(self) 实例,在定义中可以用作filter的参数很多,但是说明文档中没有给出,可以去gitlab的接口文档中查看,基本上都能满足需求。
_list_filters = ('search', 'owned', 'starred', 'archived', 'visibility',
'order_by', 'sort', 'simple', 'membership', 'statistics',
'with_issues_enabled', 'with_merge_requests_enabled',
'with_custom_attributes')
tips
函数注解
之前写函数习惯性是添加注释,其实还可以添加注解:
def func(x: int, y: callable) -> str:
pass
# print结果{'x':
print(add.__annotations__)
这种形式,只是注解,是不会其他任何附加影响的,不会说你注解了x是int,传入str报错。Python是弱类型!!
函数参数
先前的函数基础知识说说过 *args,**kwargs两种参数,倘若要一个函数,其调用只能是关键字形式传入参数可以如下定义:
def func(*, x, y, **kwargs):
pass
# 只能是关键字形式传入参数
func(x=1, y=2, option_param=3)
__str__ & __repr__
上次被人问到这两个,本来想这东西多数书上都有,但是还真有人问,那就说吧,一个是在python 的shell下直接裸给一个实例时调用,一个是print打印时调用。
>>>a = A()
# 调用__repr__
>>>a
# 调用__str__
>>>print(a)
注意:
如果只定义了一个__repr__ 此时 裸给和print都调用__repr__
如果只定义了一个__str__,裸调返回内置默认的,即平时看到给出地址号的那种,print则调用__str__。
————————————————
版权声明:本文为CSDN博主「Inevitable-Neo」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/duxiangwushirenfei/article/details/81088338