本文目录一览:
- 1、如何进行python项目配置管理?这才是你最需要的python技术
- 2、怎样在python中更新xml文件?
- 3、Python的mysql数据库的更新如何实现
- 4、centos怎么更新python
- 5、python中四种配置文件
如何进行python项目配置管理?这才是你最需要的python技术
每次开始一个新的 Python 项目,我都会为怎么管理配置文件而头疼。不过在迁移我的博客时,终于有空花了点时间,把这件事想清楚。
一年多的时间过去了,一切似乎都很顺利,连我在知乎所做的新项目也沿用了该方案,于是决定把解决方案记录下来。
先说说我要解决什么哪些Python项目的配置管理问题吧:
可以区分各种环境。
在开发、测试和生产等环境,都可能用到不同的配置,所以能区分它们是一个很基本的需求。
可以有通用的配置项。
各种环境的配置中,需要修改的只占一小部分。因此通用的部分应该不需要重复定义,否则会带来维护成本。
可以分成多个部分/模块。
随着Python项目的配置管理项的增多,找起配置来会花大量时间,所以划分它们对维护配置很有帮助。
可以直接使用 Python 代码。
从文本文件中解析出变量值太麻烦,而且不方便生成批量的数据(例如数组),也不好通过函数调用来生成配置值(例如获取文件路径)。
可以将公开和私有的配置文件分开管理。
在开源项目中,应只包含公开的配置项,而不包含私有的配置。不过这个需求对私有项目而言,没什么意义。
工作中我先后使用了几种Python项目的配置管理方式,主要使用的就两种:
为每个环境分别写一个配置文件,到相应的环境里,将该环境的配置文件软链接到正确的路径。
如何进行python项目配置管理?使用分布式的配置服务,从远程获取配置。
前者用起来其实蛮麻烦的,特别是想在本地跑单元测试时,需要替换成单元测试环境的配置文件。所以我又把环境变量给加了进来,检测到指定的环境变量,就加载单元测试的配置。而其他几个需求也能勉强实现,不过并不优雅。
后者不能直接使用 Python 代码,网络不好时需要降级成使用本地缓存,获取配置服务器的地址需要配置,配置服务器自己也需要配置,而且配置服务器还可能挂掉(知乎内网遇到过全部五台配置服务器都挂掉的情况),所以我用得比较少。
其实仔细想想就能发现,「使用 Python 代码」也就意味着是 Python 源文件,「有通用的配置项」用 Python 实现就是继承,似乎没更好的选择了。
如何进行python项目配置管理?于是定义一个 Config 类,让其他环境的配置都继承这个类:
# config/default.pyclass Config(object):
DEBUG_MODE = True
PORT = 12345
COOKIE_SECRET = 'default'
REDIS_CONFIG = {'host': 'localhost', 'port': 6379, 'db': 0} # ...
# config/development.pyfrom .default import Configclass DevelopmentConfig(Config):
COOKIE_SECRET = 'dev'
# config/unit_testing.pyfrom .default import Configclass UnitTestingConfig(Config):
REDIS_CONFIG = {'host': 'localhost', 'port': 6379, 'db': 1}
# config/production.pyfrom .default import Configclass ProductionConfig(Config):
COOKIE_SECRET = '...'
REDIS_CONFIG = {'unix_socket_path': '/tmp/redis.sock'}
为了让每种环境都只有一个配置生效,还需要加一个策略:[page]
# config/__init__.pyimport loggingimport os
env = os.getenv('ENV') # 可以改成其他名字,自己进行设置try: if env == 'PRODUCTION': from .production import
ProductionConfig as CONFIG
logging.info('Production config loaded.') elif env == 'TESTING': from .testing import TestingConfig as CONFIG
logging.info('Testing config loaded.') elif env == 'UNIT_TESTING': from .unit_testing import UnitTestingConfig as
CONFIG
logging.info('Unit testing config loaded.') else: # 默认使用本地开发环境的配置,省去设置环境变量的环节
from .development import DevelopmentConfig as CONFIG
logging.info('Development config loaded.')except ImportError:
logging.warning('Loading config for %s environment failed, use default config instead.', env or 'unspecified')
from .default import Config as CONFIG
这样只需要在跑应用前,设置不同的环境变量即可。如果是用 Supervisor 维护进程的话,加上一行environment = ENV="PRODUCTION"配置即可。
当然还可以加其他的规则,例如没环境变量时,再检查机器名等。
如何进行python项目配置管理?现在前两个需求都解决了,再来看分模块的功能。
这个需求正好对应 Python 的 package,于是把每个Python项目的配置管理文件改成一个 package 即可。接着是如何同时满足第二和第三个需求。
举例来说,有这样的配置:
# config/default.pyclass Config(object):
ROOT_PATH = '/'
LOGIN_PATH = ROOT_PATH + 'login'
SCHEME = 'http'
DOMAIN = 'localhost'
ROOT_URL = '%s://%s%s' % (SCHEME, DOMAIN, ROOT_PATH)
# config/production.pyfrom .default import Configclass ProductionConfig(Config):
ROOT_PATH = '/blog/'
LOGIN_PATH = ROOT_PATH + 'login'
DOMAIN = ''
ROOT_URL = '%s://%s%s' % (Config.SCHEME, DOMAIN, ROOT_PATH)
其中,LOGIN_PATH 和 LOGIN_URL 的设置逻辑其实是一样的,但值却不同,在 ProductionConfig 中重新赋值一次有点不太优雅。
于是把这些设置提取出来,在基本设置初始化以后,再进行设置:
class _AfterMeta(type):
def __init__(cls, name, bases, dct):
super(_AfterMeta, cls).__init__(name, bases, dct)
cls._after()class Config(object):
__metaclass__ = _AfterMeta
ROOT_PATH = '/'
SCHEME = 'http'
DOMAIN = 'localhost' @classmethod
def _after(cls):
cls.LOGIN_PATH = cls.ROOT_PATH + 'login'
cls.ROOT_URL = '%s://%s%s' % (cls.SCHEME, cls.DOMAIN, cls.ROOT_PATH)
# config/production.pyfrom .default import Configclass ProductionConfig(Config):
ROOT_PATH = '/blog/'
DOMAIN = ''
如何进行python项目配置管理?所有有依赖的设置项,都在 _after 方法里赋值即可。
不过这样可能导致静态检查和代码提示出问题,而且使得所有子类都重新定义这些属性,即便没有修改父类的属性,或是覆盖掉手动设置的值。所以可以再修改一下:[page]
class _AfterMeta(type):
def __init__(cls, name, bases, dct):
super(_AfterMeta, cls).__init__(name, bases, dct)
cls._after(dct)class Config(object):
__metaclass__ = _AfterMeta
ROOT_PATH = '/'
LOGIN_PATH = ROOT_PATH + 'login'
SCHEME = 'http'
DOMAIN = 'localhost'
ROOT_URL = '%s://%s%s' % (SCHEME, DOMAIN, ROOT_PATH) @classmethod
def _after(cls, own_attrs):
if 'LOGIN_PATH' not in own_attrs and 'ROOT_PATH' in own_attrs:
cls.LOGIN_PATH = cls.ROOT_PATH + 'login'
if 'ROOT_URL' not in own_attrs and ('SCHEME' in own_attrs or 'DOMAIN' in own_attrs or 'ROOT_PATH' in
own_attrs):
cls.ROOT_URL = '%s://%s%s' % (cls.SCHEME, cls.DOMAIN, cls.ROOT_PATH)
虽然问题是解决了,不过代码量似乎大了点,写起来很麻烦。只是似乎也没有更好解决办法,所幸这类配置并不多,所以重写一次倒也无妨。
最后只剩下分离公开和私有配置这个需求了。
既然要有私有配置,很容易想到的就是把私有配置放在另一个仓库里,再 link 到配置文件夹即可:
└── config
├── __init__.py
├── default.py
├── development.py - private/development.py
├── development_sample.py
├── private (cloned from another private repository)
│ ├── development.py
│ └── production.py
├── production.py - private/production.py
└── production_sample.py
为了避免文件被提交到公共仓库,私有的配置文件可以加到 .gitignore 里。
顺带一提,我的博客数据全存放在 Redis 中,备份时只要备份 rdb 文件即可。不过用另一台服务器来备份显得太奢侈了,所以我在服务器上装了个 Dropbox,然后把 Dropbox 文件夹里的数据文件夹 link 到博客的数据文件夹里,即:
doodle
└── data
└── redis - ~/Dropbox/doodle/redis
这样一旦文件有改动,Dropbox 就会自动进行备份,而且保留了所有的历史版本,简直完美。
如何进行python项目配置管理?这才是你最需要的python技术,我用于创建和管理虚拟环境的模块称为 venv。venv 通常会安装你可用的最新版本的 Python。如果您的系统上有多个版本的 Python,你能处理好吗?如果您还担心自己入门不顺利,那么本科目的其他文章一定会帮助你。
怎样在python中更新xml文件?
其实有两种解析方式:
SAX(基于事件的解析方法,部分载入)
DOM(全部载入,内存消耗太多,改进方法:载入子树,延迟读)
python中可用,elementtree, minidom都是可以的
Python的mysql数据库的更新如何实现
MySQL 的 Binlog 记录着 MySQL 数据库的所有变更信息,了解 Binlog 的结构可以帮助我们解析Binlog,甚至对 Binlog 进行一些修改,或者说是“篡改”,例如实现类似于 Oracle 的 flashback 的功能,恢复误删除的记录,把 update 的记录再还原回去等。本文将带您探讨一下这些神奇功能的实现,您会发现比您想象地要简单得多。本文指的 Binlog 是 ROW 模式的 Binlog,这也是 MySQL 8 里的默认模式,STATEMENT 模式因为使用中有很多限制,现在用得越来越少了。
Binlog 由事件(event)组成,请注意是事件(event)不是事务(transaction),一个事务可以包含多个事件。事件描述对数据库的修改内容。
现在我们已经了解了 Binlog 的结构,我们可以试着修改 Binlog 里的数据。例如前面举例的 Binlog 删除了一条记录,我们可以试着把这条记录恢复,Binlog 里面有个删除行(DELETE_ROWS_EVENT)的事件,就是这个事件删除了记录,这个事件和写行(WRITE_ROWS_EVENT)的事件的数据结构是完全一样的,只是删除行事件的类型是 32,写行事件的类型是 30,我们把对应的 Binlog 位置的 32 改成 30 即可把已经删除的记录再插入回去。从前面的 “show binlog events” 里面可看到这个 DELETE_ROWS_EVENT 是从位置 378 开始的,这里的位置就是 Binlog 文件的实际位置(以字节为单位)。从事件(event)的结构里面可以看到 type_code 是在 event 的第 5 个字节,我们写个 Python 小程序把把第383(378+5=383)字节改成 30 即可。当然您也可以用二进制编辑工具来改。
找出 Binlog 中的大事务
由于 ROW 模式的 Binlog 是每一个变更都记录一条日志,因此一个简单的 SQL,在 Binlog 里可能会产生一个巨无霸的事务,例如一个不带 where 的 update 或 delete 语句,修改了全表里面的所有记录,每条记录都在 Binlog 里面记录一次,结果是一个巨大的事务记录。这样的大事务经常是产生麻烦的根源。我的一个客户有一次向我抱怨,一个 Binlog 前滚,滚了两天也没有动静,我把那个 Binlog 解析了一下,发现里面有个事务产生了 1.4G 的记录,修改了 66 万条记录!下面是一个简单的找出 Binlog 中大事务的 Python 小程序,我们知道用 mysqlbinlog 解析的 Binlog,每个事务都是以 BEGIN 开头,以 COMMIT 结束。我们找出 BENGIN 前面的 “# at” 的位置,检查 COMMIT 后面的 “# at” 位置,这两个位置相减即可计算出这个事务的大小,下面是这个 Python 程序的例子。
切割 Binlog 中的大事务
对于大的事务,MySQL 会把它分解成多个事件(注意一个是事务 TRANSACTION,另一个是事件 EVENT),事件的大小由参数 binlog-row-event-max-size 决定,这个参数默认是 8K。因此我们可以把若干个事件切割成一个单独的略小的事务
ROW 模式下,即使我们只更新了一条记录的其中某个字段,也会记录每个字段变更前后的值,这个行为是 binlog_row_image 参数控制的,这个参数有 3 个值,默认为 FULL,也就是记录列的所有修改,即使字段没有发生变更也会记录。这样我们就可以实现类似 Oracle 的 flashback 的功能,我个人估计 MySQL 未来的版本从可能会基于 Binlog 推出这样的功能。
了解了 Binlog 的结构,再加上 Python 这把瑞士军刀,我们还可以实现很多功能,例如我们可以统计哪个表被修改地最多?我们还可以把 Binlog 切割成一段一段的,然后再重组,可以灵活地进行 MySQL 数据库的修改和迁移等工作。
centos怎么更新python
不知道你是centos6及python版本,一下是centos6 2.6升级到2.7的方法,对应找到相应的版本就可以了。。
=======================================================
Centos系统一般默认就安装有Python2.6.6版本,不少软件需要2.7以上的,通过包管理工具安装不了最新的版本,通过源码编译可以方便安装指定版本,只需要把下面版本的数字换成你想要的版本号。
1.安装步骤
下载源码
wget
在下载目录解压源码
tar -zxvf Python-2.7.12.tgz
进入解压后的文件夹
cd Python-2.7.12
编译前先在/usr/local建一个文件夹python2.7.12(作为python的安装路径,以免覆盖老的版本,新旧版本可以共存的)
mkdir /usr/local/python2.7.12
编译前需要安装下面依赖,否则下面安装pip就会出错
yum install openssl openssl-devel zlib-devel gcc -y
安装完依赖后执行下面命令
vim ./Modules/Setup
找到#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz去掉注释并保存(即去掉井号)
在解压缩后的目录下编译安装
./configure --prefix=/usr/local/python2.7.12 --with-zlib
make
make install
此时没有覆盖老版本,再将原来/usr/bin/python链接改为别的名字
mv /usr/bin/python /usr/bin/python2.6.6
再建立新版本python的软链接
ln -s /usr/local/python2.7.12/bin/python2.7 /usr/bin/python
这个时候输入
python
就会显示出python的新版本信息
Python 2.7.12 (default, Oct 13 2016, 03:17:14)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-17)] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
2.修改yum配置文件
之所以要保留旧版本,因为yum依赖Python2.6,改下yum的配置文件,指定旧的Python版本就可以了。
vim /usr/bin/yum,将第一行的#!/usr/bin/python修改成#!/usr/bin/python2.6.6
3.安装最新版本的pip
wget
python get-pip.py
找到pip2.7的路径
find / -name "pip*"
上面的命令输出
/root/.cache/pip
这里省略一堆输出
/usr/local/python2.7.12/bin/pip
/usr/local/python2.7.12/bin/pip2
/usr/local/python2.7.12/bin/pip2.7 #就是这个
/usr/bin/pip
/usr/bin/pip2
/usr/bin/pip2.6
为其创建软链作为系统默认的启动版本(之前有旧版本的话就先删掉rm -rf /usr/bin/pip)
ln -s /usr/local/python2.7.12/bin/pip2.7 /usr/bin/pip
看下pip的版本
pip -V
pip 8.1.2 from /usr/local/python2.7.12/lib/python2.7/site-packages (python 2.7)
pip安装完毕,现在可以用它下载安装各种包了
python中四种配置文件
常用的配置文件后缀是.ini、.conf、.py,当然还有使用.json、.txt的,推荐使用常用的.ini、.py,配置文件的名字一般是config便于理解和使用。
ini配置文件,这类配置文件我们使用内置configparser库来使用,它可以实现配置文件的写入、更新、删除、读取等操作非常方便,建议使用这种方式。
新建一个config.ini的配置文件内容如下,编码格式要是 utf-8 以免出错。:
其中[]中的是section节点,该节点下的等式是option即键=值
然后每一行写一个option ,每个选项就是一个option。直接写名字,后面加 " = " 再加上它的值就行,字符串的表示不要加引号,否则引号也会被解析出来。
可以在配置文件中加入注释 ,但是注释必须是单独的一行,且以 “#” 开头。只是每次运行时不会读入注释,只要运行一次,写入文件后,所有的注释都会消失。
config.json文件
使用python内置的 json 标准库进行解析ini文件。
load() 从json文件中读取json格式数据
loads() 将字符串类型数据转化为json格式数据
dump() 将json格式数据保存到文件
dumps() 将json格式数据保存为字符串类型
TOML的语法广泛地由key = "value"、[节名]、#注释构成。
支持以下数据类型:字符串、整形、浮点型、布尔型、日期时间、数组和图表。
config.toml文件
使用外部库 toml 解析toml文件。
安装:pip install toml
读取文件
安装:
YAML是目前最推荐的配置文件格式。优秀的配置文件标准它几乎都有:
容易阅读和修改,支持注释。
支持丰富的数据类型。
不同格式的明确表达。
yaml使用时需要注意:
yaml强制缩进。虽然不规定具体缩进几个空格,但是同一级的内容要保持相同的缩进。
冒号后面一定要加空格, 否则无法解析。
python解析 yaml 可以使用pyyaml库,操作和标准的文件操作非常类似:
得到的data就是解析后的数据,在python当中,它是一个嵌套的字典:
想获取某一项配置,再通过字典的操作获取:
config.yaml文件
读取