pytest的简单学习

Pytest 的简单学习 一、介绍及下载安装 [[Pytest]] 是 [[Python]] 的一种单元测试框架,与 python 自带的 unittest 测试框架类似,但是比 unittest 框架使用起来更简洁,效率更高。 其主要使用 assert 断言对单元方法记性测试 其有个 fixture 类,可以减少资源占用,资源的统一调度 安装:pip install -U pytest 测试: py.test --version 或者 pytest --version 二、基础单元测试(assert 断言) assert 断言是 python 标准语法里的东西 asset 后是一个返回布尔值的表达式 若为真,则通过;若为假,抛出异常 # example >>>assert 1 == 1 >>>assert 2+2 == 2*2 >>>assert len('hello') < 10 >>>assert len('hello') > 10 Traceback (most recent call last): File "<stdin>", line 1, in <module> AssertionError >>>assert len('hello') > 10, '字符串长度小于10' Traceback (most recent call last): File "<stdin>", line 1, in <module> AssertionError: 字符串长度小于10 >>>assert range(4) == [0,1,2,3] 通过上面关于 assert 的例子,可以看出很适合单元测试。 ...

Python 新式类和旧式类

Python [[OOP]] Python 新式类和旧式类 新式类从 python2.2 开始引入。 定义区别 # python2.x class A: # 旧式类 pass class B(object): # 新式类 pass class C(A): # 旧式类,因为 A 是旧式类 pass class D(B): # 新式类 pass class E(A, B): # 新式类 pass class F(B, A): # 新式类 # python3.x class A: # python3.x 全是新式类 pass 使用区别 __class__ 执行结果和type不一致 继承搜索的顺序 __slots__ __getattribute__ 对新式类的实例执行 a.__class__ 与 type(a) 的结果是一致的,对于旧式类来说就不一样了。 >>> class A: ... pass >>> a = A() >>> a <__main__.A instance at 0x10654bc68> >>> a.__class__ <class __main__.A at 0x1064cec18> >>> type(a) <type 'instance'> >>> class B(object): ... pass ... >>> b = B() >>> b.__class__ <class '__main__.B'> >>> type(b) <class '__main__.B'> 继承搜索的顺序 class A(): def __init__(self): pass def save(self): print "This is from A" class B(A): def __init__(self): pass class C(A): def __init__(self): pass def save(self): print "This is from C" class D(B,C): def __init__(self): pass fun = D() fun.save() 经典类的答案: This is from A 新式类的答案: This is from C ...

python 类的实例化的全过程

Python [[OOP]] python 类的实例化的全过程 开篇 一直以来使用 Python 里的类,都是先写类名,然后 __init__, 并且 Python 变量不需要声明类型的,就理所应当的觉得 Python 里没有 new,不像是 Java 或者 C# 那样使用一个对象前要先 new 一个出来,然后再实例化。 结果是 Python 里有 __new__ 这个概念,但是大部分情况下会被隐藏,我们可以先定义一个类,然后 dir(cls) 看下有哪些方法。 __new__ 是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在 Python 中存在于类里面的构造方法 __init__ 负责将类的实例化,而在 __init__ 启动之前,__new__ 决定是否要使用该 __init__ 方法,因为 __new__ 可以调用其他类的构造方法或者直接返回别的对象来作为本类的实例。 如果将类比喻为工厂,那么 __init__ 方法则是该工厂的生产工人,__init__ 方法接受的初始化参数则是生产所需原料,__init__ 方法会按照方法中的语句负责将原料加工成实例以供工厂出货。而 __new__ 则是生产部经理,__new__ 方法可以决定是否将原料提供给该生产部工人,同时它还决定着出货产品是否为该生产部的产品,因为这名经理可以借该工厂的名义向客户出售完全不是该工厂的产品。 __new__() 方法的特性: __new__() 方法是在类准备将自身实例化时调用。 __new__() 方法始终都是类的静态方法,即使没有被加上静态方法装饰器。 new 和 init 先来定义个类: class Test(object): def __init__(self, *args, **kwargs): print("in init...") test = Test() 上述代码会输出一句 “in init”,但是它隐藏了对 __new__ 的调用,再来定义个类。 ...

Python 连接 MySQL

MySQL database Python Python 连接 MySQL 使用接口 Python DB API,两种情况: python2.7,使用 Python-MySQL connector,载入语句 import MySQLdb python3.4,安装 pymysql 模块,载入语句 import pymysql Connection对象: 创建方法:pymysql.Connect(host,port,user,passwd,db) 支持方法: 1、cursor(),使用该连接创建并返回游标 2、commit(),提交当前事务 3、rollback(),回滚当前事务 4、close(),关闭连接 cursor游标对象:用于执行查询和获取结果 支持方法: 1、execute(op,[args]),执行一个数据库查询和命令 2、fetchone(),取得结果集的下一行 3、fetchmany(size),取得结果集的下几行 4、fetchall(),取得结果集的剩下的所有行 5、rowcount,最近一次execute返回数据的行数或影响行数 6、close(),关闭游标对象 select查询数据操作过程 开始 创建connection 创建cursor 使用cursor.excute()执行select语句 使用cursor.fetch*()获取并处理数据 关闭cursor 关闭connection -结束 insert/update/delete更新数据库操作过程 开始 创建connection 创建cursor 使用cursor.excute()执行insert/update/delete语句 -出现异常:使用connection.rollback()回滚事务 未出现异常:使用connection.commit()提交事务 关闭cursor 关闭connection 结束

Python2 字符串问题

Python Python2 字符串问题 原谅我这一生不羁放纵爱自由 也会怕有一天会跌倒 Hoo No 字符串在python中的使用很多,而且字符串也很多种类,本身也有很多方法,例如replace,len,startswith,endwith,split等等,本文着重于字符串和编码之间的关系。 Python2 的字符串,一般不会出问题,遇到中英文混编的时候就会很糊涂,查了些资料,由于时代的限制,当时的字符串设计仅对纯英文友好,更不必谈混编,后来的 2.7.x 版本已经做的很好了,但是真遇到问题会比较绕,内部的处理机制完全不符合 Python 设计哲学的 Simple is better than complex。 关于字符编码的历史问题,已经目前常用的编码以及转换,可以看字符串和编码。 归根结底:str其实并不是字符串而是字节串(八位二进制数据串),而Unicode字符串对象才是真正的字符串。 总结的解决方案为:读取到字节串数据后根据实际编码格式解码(decode)成 Unicode 字符串对象,使用 Unicode 对象处理字符串,输出到控制台时用 Unicode 字符串对象,保存数据到文件时将字符串编码(encode)成 utf-8 编码格式字节串数据。如果是代码里面创建的字符串对象,遇到中英文混排的情况,尽量使用 Unicode 来避免 UnicodeEncodeError。 更多的文章可以参考: Python2字符串编码问题总结 Python2和Python3之间关于字符串编码处理的差别

Python打包文件夹

使用[[Python]]对指定目录进行打包。 zip import os, zipfile #打包目录为zip文件(未压缩),空目录会被忽略 def make_zip(source_dir, output_filename): zipf = zipfile.ZipFile(output_filename, 'w') pre_len = len(os.path.dirname(source_dir)) for parent, dirnames, filenames in os.walk(source_dir): for filename in filenames: pathfile = os.path.join(parent, filename) arcname = pathfile[pre_len:].strip(os.path.sep) #相对路径 zipf.write(pathfile, arcname) zipf.close() tar/tar.gz import os, tarfile #一次性打包整个根目录。空子目录会被打包。 #如果只打包不压缩,将"w:gz"参数改为"w:"或"w"即可。 def make_targz(output_filename, source_dir): with tarfile.open(output_filename, "w:gz") as tar: tar.add(source_dir, arcname=os.path.basename(source_dir)) import os, tarfile #逐个添加文件打包,未打包空子目录。可过滤文件。 #如果只打包不压缩,将"w:gz"参数改为"w:"或"w"即可。 def make_targz_one_by_one(output_filename, source_dir): tar = tarfile.open(output_filename,"w:gz") for root,dir,files in os.walk(source_dir): for file in files: pathfile = os.path.join(root, file) tar.add(pathfile) tar.close()

RAID 的概念以及 RAID 卡的配置

RAID RAID 的概念以及 RAID 卡的配置 RAID 基础概念 基本原理 RAID ( Redundant Array of Independent Disks )即独立磁盘冗余阵列,通常简称为磁盘阵列。简单地说, RAID 是由多个独立的高性能磁盘驱动器组成的磁盘子系统,从而提供比单个磁盘更高的存储性能和数据冗余的技术。 RAID 是一类多磁盘管理技术,其向主机环境提供了成本适中、数据可靠性高的高性能存储。 SNIA 对 RAID 的定义是 :一种磁盘阵列,部分物理存储空间用来记录保存在剩余空间上的用户数据的冗余信息。当其中某一个磁盘或访问路径发生故障时,冗余信息可用来重建用户数据。磁盘条带化虽然与 RAID 定义不符,通常还是称为 RAID (即 RAID0 )。 这里要提一下 JBOD ( Just a Bunch of Disks )。最初 JBOD 用来表示一个没有控制软件提供协调控制的磁盘集合,这是 RAID 区别与 JBOD 的主要因素。目前 JBOD 常指磁盘柜,而不论其是否提供 RAID 功能。 软/硬 RAID 软件 RAID:操作系统下实现 RAID,软 RAID 不能保护系统盘。亦即系统分区不能参与实现 RAID。有些操作系统,RAID 的配置信息存在系统信息中,而不是存在硬盘上;当系统崩溃,需重新安装时,RAID 的信息也会丢失。 硬件 RAID:是采用集成的阵列卡或专用的阵列卡来控制硬盘驱动器,这样可以极大节省服务器系统 CPU 和操作系统的资源。从而使服务器的性能获得很大的提高。 RAID 的分类 RAID等级 RAID0 RAID1 RAID5 RAID6 RAID10 别名 条带 镜像 分布奇偶校验条带 双重奇偶校验条带 镜像加条带 容错性 无 有 有 有 有 冗余类型 无 有 有 有 有 热备盘 无 有 有 有 有 读性能 高 低 高 高 高 随机写性能 高 低 一般 低 一般 连续写性能 高 低 低 低 一般 需要磁盘数 n≥1 2n (n≥1) n≥3 n≥4 2n(n≥2)≥4 可用容量 全部 50% (n-1)/n (n-2)/n 50% RAID 的优势 大容量 这是 RAID 的一个显然优势,它扩大了磁盘的容量,由多个磁盘组成的 RAID 系统具有海量的存储空间。现在单个磁盘的容量就可以到 1TB 以上,这样 RAID 的存储容量就可以达到 PB 级,大多数的存储需求都可以满足。一般来说, RAID 可用容量要小于所有成员磁盘的总容量。不同等级的 RAID 算法需要一定的冗余开销,具体容量开销与采用算法相关。如果已知 RAID 算法和容量,可以计算出 RAID 的可用容量。通常, RAID 容量利用率在 50% ~ 90% 之间。 ...

redhat 系使用 scl 工具临时使用高级开发工具

Linux [[RedHat]] redhat 系使用 scl 工具临时使用高级开发工具 最近在做一次编译任务中,出现了 cc 指令错误,显示未找到 a.c 文件,猜测可能因为 gcc 版本问题。检测到可以在 Ubuntu 18.04 正常编译使用的 gcc 版本是 7.5,而基于 Centos7 的 Aliyun Linux 2.1903 却还是 4.8 版本。先升级 gcc 版本再测试编译问题。 在 redhat 系中升级 gcc 有两种方案,一种是下载源码进行编译,另外一种是借助 scl 工具。前者不推荐,一是因为编译速度慢,二是因为编译可能出现各种问题需要手动处理。后者 SCL 软件集(Software Collections)是为了给 RHEL/CentOS 用户提供一种以方便、安全地安装和使用应用程序和运行时环境的多个(而且可能是更新的)版本的方式,同时避免把系统搞乱。 普通 RHEL/Centos 使用 scl # 安装 scl 源: $ yum install centos-release-SCL scl-utils-build # 查看从 scl 中安装的包的列表: $ scl –list # 列出 scl 源有哪些包可以用: $ yum list all --enablerepo='centos-sclo-rh' # 安装高版本的 gcc、gcc-c++ yum install devtoolset-7-gcc devtoolset-7-gcc-c++ # devtoolset-3: gcc 4.9 # devtoolset-4: gcc 5 # devtoolset-6: gcc 6 # devtoolset-7: gcc 7 # devtoolset-8: gcc 8 # 测试下是否成功 $ scl enable devtoolset-7 'gcc --version' gcc (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5) Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Aliyun Linux 2.1903 使用 scl # 先安装scl-utils $ yum install -y scl-utils # 打开YUM仓库支持 $ yum install -y alinux-release-experimentals # 从YUM源安装您需要的软件包,以下示例命令同时安装了SCL插件方式支持的所有开发工具包 $ yum install -y devtoolset-7-gcc devtoolset-7-gdb devtoolset-7-binutils devtoolset-7-make # 运行相关的SCL软件 $ scl enable devtoolset-7 'gcc --version' gcc (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5) Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 使用高版本的开发工具 使用绝对路径 添加可执行文件路径到 PATH 环境变量 使用官方推荐的加载命令:scl enable devtoolset-x bash, x为要启用的版本 执行安装软件自带的脚本: source /opt/rh/devtoolset-x/enable,x为要启用的版本 推荐后两种方案。 ...

redis 安装使用

database Redis redis 安装使用 # 安装并编译 wget https://download.redis.io/releases/redis-6.0.9.tar.gz -O /tmp/redis-6.0.9.tar.gz cd /tmp tar xzf redis-6.0.9.tar.gz cd redis-6.0.9 make # 创建环境 BASE_PATH=/opt/redis-single-point mkdir -p $BASE_PATH mkdir -p $BASE_PATH/bin mkdir -p $BASE_PATH/conf mkdir -p $BASE_PATH/data mkdir -p $BASE_PATH/log/ cp /tmp/redis-6.0.9/src/redis-server /tmp/redis-6.0.9/src/redis-cli /tmp/redis-6.0.9/src/redis-benchmark $BASE_PATH/bin # 配置 redis.conf vi $BASE_PATH/conf/redis.conf bind 127.0.0.1 protected-mode no port 4399 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize yes supervised no pidfile /var/run/redis_6379.pid loglevel notice logfile "/opt/redis-single-point/log/redis.log" databases 16 always-show-logo yes save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb rdb-del-sync-files no dir /opt/redis-single-point/data/ replica-serve-stale-data yes replica-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-diskless-load disabled repl-disable-tcp-nodelay no replica-priority 100 acllog-max-len 128 lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no replica-lazy-flush no lazyfree-lazy-user-del no oom-score-adj no oom-score-adj-values 0 200 800 appendonly no appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes aof-use-rdb-preamble yes lua-time-limit 5000 cluster-enabled no cluster-node-timeout 15000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 stream-node-max-bytes 4096 stream-node-max-entries 100 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 dynamic-hz yes aof-rewrite-incremental-fsync yes rdb-save-incremental-fsync yes jemalloc-bg-thread yes # 配置 redis 服务 vi /lib/systemd/system/redis.service [Unit] Description=redis service port 6379 [Service] User=Development Group=Development Type=forking ExecStart=/opt/redis-single-point/bin/redis-server /opt/lotus/redis-single-point/conf/redis.conf Restart=on-success [Install] WantedBy=multi-user.target # 启动服务并检测 systemctl daemon-reload systemctl start redis ps -ef|grep redis echo 'export PATH=$PATH:/opt/redis-single-point/bin' >> /etc/profile source /etc/profile redis-cli -h 127.0.0.1 -p 6379 redis>

redis 集群搭建

database Redis redis 集群搭建 高可用方案 一般常用的有两种高可用方案: redis 哨兵 redis 集群 在 redis 早期版本中,只能使用哨兵模式,但这种模式下,需要多一个守护对资源进行监控,并且在 master 断掉的时候切换过程比较慢。 在 5.0 之后,一般推荐使用 redis 集群方案实现高可用。 操作环境 使用了三台机器,以三主三从的方案进行部署,在一台机器上部署一主一从,其中 8001 是主节点,8002 是从节点。 redis01: 192.168.0.2 redis02: 192.168.0.3 redis03: 192.168.0.4 虽然这三台机器都是 Ubuntu Server 18.04,但是内核版本都不相同,所以都是单独执行的编译过程。 决定不使用系统空间,而使用 /opt/ 的上 TB 空间。 所有 redis 相关的数据都在 /opt/redis/ 下面: bin/ 二进制程序 conf/ 配置文件 data/ 运行产生文件 log/ 日志文件 redis-6.0.7/ 源代码 部署过程 主要是配置文件的处理: 主节点配置以下参数: daemonize yes port 8001 dir /opt/redis/data/master cluster-enabled yes cluster-config-file /opt/redis/conf/nodes-8001.conf cluster-node-timeout 15000 #bind 127.0.0.1 protected-mode no appendonly yes requirepass abcdefg masterauth abcdefg logfile /opt/redis/log/redis-master-8081.log 从节点配置以下参数: ...