1 模块的动态导入
先看样例代码
idc_module = __import__('cloudm.ext.provider.{idc}'.format(idc=idc), fromlist=[idc.title()])
idc_provider = getattr(idc_module, idc.title())
client = idc_provider(access_key, secret_key, region, **kwargs)
代码的意思是根据变量idc是阿里云、AWS、腾讯云、OpenStack,动态的导入其SDK,然后创建云服务操作的client端。
动态导入的好处就是使代码变得更整洁更可读。
其中formlist参数不太好理解,这个参数是非必选。
假设{idc}=aws,idc.title=AWS如果没有fromlist参数
idc_module = __import__('cloudm.ext.provider.{idc}'.format(idc=idc))
相当于importcloudm.ext.provider.aws,返回的是顶层模块;
idc_module = __import__('cloudm.ext.provider.{idc}'.format(idc=idc), fromlist=[idc.title()])
相当于from cloudm.ext.provider.awsimport AWS,返回的是AWS这个类
2 反射4函数getattr、hasattr、setattr、delattr
从上面案例可以看出,反射4函数是python中配合动态加载模块的神器,当然其应用场景很广。
getattr(object, name[,default])
获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,可以在后面添加一对括号。
setattr(object, name, values)
给对象的属性赋值,若属性不存在,先创建再赋值。
hasattr(object, name)
判断一个对象里面是否有name属性或者name方法,返回BOOL值,有name特性返回True,否则返回False。
delattr(object, name)
从一个对象里删除某个属性
3 @classmethod的使用
Python中用@classmethod修饰的函数就像是Java中的public static 修饰的方法一样,属于类级别的静态方法可以不用创建对象直接调用。主要用来定义一些辅助函数、共用函数,如下案例,定义了一个时间转换工具函数
@classmethod
def time2stamp(cls, dt):
t = '{year}{month}{day}{hour}{minute}{second}'.format(
year=dt.year, month=dt.month, day=dt.day,
hour=dt.hour, minute=dt.minute, second=dt.second)
timestamp = datetime.strptime(
t,
'%Y%m%d%H%M%S').strftime('%s')
return int(timestamp)
4 查看模块版本
如果我要查看安装的Django版本,执行以下命令
$pip list | grep Django
5 python创建新进程执行linux命令
stderr = sys.stderr
stdout = sys.stdout
environ_vars = os.environ.copy()
p = subprocess.Popen(cmd, stdout=stdout, stderr=stderr,
shell=True, env=environ_vars)
当shell=True时,表示在系统默认的shell环境中执行新的进程,此shell在windows表示为cmd.exe,在linux为/bin/sh。、
其中stdout、stderr、stdin是linux基础里的知识,分别代表着正常输出、错误输出和输入。可选的值有PIPE或者一个有效的文件描述符(其实是个正整数)或者一个文件对象,还有None。如果是PIPE,则表示需要创建一个新的管道,如果是None,不会做任何重定向工作,子进程的文件描述符会继承父进程的。另外,stderr的值还可以是STDOUT,表示子进程的标准错误也输出到标准输出。
举个用管道pipe的例子:
p=subprocess.Popen("df -h",shell=True,stdout=subprocess.PIPE)
out=p.stdout.readlines()
6 requests模块
案例
Import requests
resp = requests.post(inventory_api, data=json.dumps(resource))
ret = json.loads(resp.text)
这个模块在python后台很实用,发起http各种请求都很方便,配合json模块如虎添翼。
7 re模块
Python中用于正则表达式判断的模块,使用场景比较丰富,如下案例:
if re.search('^(alicloud|aws|tencentcloud|openstack_compute)_instance', k):
continue
代码的意思是判断k的内容是否由alicloud、aws、tencentcloud、openstack_compute加_instance开头的。
re的详细用法如下:
普通字符 | 匹配自身 | abc | abc |
. | 匹配任意除换行符"\n"外的字符(在DOTALL模式中也能匹配换行符 | a.c | abc |
\ | 转义字符,使后一个字符改变原来的意思 | a\.c;a\\c | a.c;a\c |
* | 匹配前一个字符0或多次 | abc* | ab;abccc |
+ | 匹配前一个字符1次或无限次 | abc+ | abc;abccc |
? | 匹配一个字符0次或1次 | abc? | ab;abc |
^ | 匹配字符串开头。在多行模式中匹配每一行的开头 | ^abc | abc |
$ | 匹配字符串末尾,在多行模式中匹配每一行的末尾 | abc$ | abc |
| | 或。匹配|左右表达式任意一个,从左到右匹配,如果|没有包括在()中,则它的范围是整个正则表达式 | abc|def | abc def |
{} | {m}匹配前一个字符m次,{m,n}匹配前一个字符m至n次,若省略n,则匹配m至无限次 | ab{1,2}c | abc abbc |
[] | 字符集。对应的位置可以是字符集中任意字符。字符集中的字符可以逐个列出,也可以给出范围,如[abc]或[a-c]。[^abc]表示取反,即非abc。 所有特殊字符在字符集中都失去其原有的特殊含义。用\反斜杠转义恢复特殊字符的特殊含义。 | a[bcd]e | abe ace ade
|
() | 被括起来的表达式将作为分组,从表达式左边开始没遇到一个分组的左括号“(”,编号+1. 分组表达式作为一个整体,可以后接数量词。表达式中的|仅在该组中有效。 | (abc){2} a(123|456)c | abcabc a456c |
8 Click Annotation
@click是python的命令行工具,可以将python代码转化成命令行的方式来调用。
例如agent.py文件:
import click
@click.command()
@click.option('--conf', default='app.yaml', required=True, help='resource config')
def run(conf, cmd):
config_data = json.loads(conf)
#
if __name__:
run()
这样就可以用Python angen.py --conf=”key-value-json”这种方式来调该python了,并且可以传入相关参数,相当于把python文件变成了一条命令。