day7

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了day7相关的知识,希望对你有一定的参考价值。

1、python 函数式+面向对象

2、函数式编程,面向对象编程实现:发送邮件的功能
# 函数
def mail(email, message):
print("去发吧")
return True

mail("[email protected]", "好人")

面向对象:类,对象

class Foo:

# 方法
def mail(self, email, message):
print(‘去发吧‘)
return True

# 调用
1、创建对象,类名()
obj = Foo()
2、通过对象去执行方法
obj.mail("[email protected]", "好人")



3、类和对象

a. 创建类
class 类名:

def 方法名(self,xxxx):
pass

b. 创建对象
对象 = 类名()

c. 通过对象执行方法
对象.方法名(123)



4、函数式 与 面向对象 对比

函数式:

def fetch(host, username, password, sql):
pass
def create(host, username, password, sql):
pass
def remove(host, username, password, nid):
pass
def modify(host, username, password, name):
pass
...

fetch(....)


面向对象:

class SQLHelper:

def fetch(self, sql):
pass

def create(self, sql):
pass
def remove(self, nid):
pass
def modify(self, name):
pass

obj1 = SQLHelper() #下面三个动态字段封装到obj1对象中,就等于self中封装了这三个值
obj1.hhost = "c1.salt.com"
obj1.uuserane = "alex"
obj1.pwd = "123"

obj1.fetch("select * from A")

obj2 = SQLHelper()
obj2.hhost = "c2.salt.com"
obj2.uuserane = "alex"
obj2.pwd = "123"

obj2.fetch("select * from A")

 

一. 模块

上一期博客里列出了几个常用模块(os,hashlib,sys,re), 还有几个剩余的,这篇来继续往下走。

1. configparser模块

configparser模块是Python自带模块,主要用于处理特定的文件(ini文件),格式比较像mysql的配置文件类型,就是文件中有多个section,每个section下面有多个配置项,如下:

技术分享
[mysqld]
basedir = /usr/local/mysql
datadir = /data/mysql
socket = /data/mysql/mysql.sock

[client]
host = localhost
port = 3306
socket = /data/mysql/mysqld.sock
技术分享

假定配置文件名字是 my.cnf

(1)获取所有节点(section):使用sections() 方法

技术分享
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Author: DBQ(Du Baoqiang)


import configparser

config = configparser.ConfigParser()   #先把config应用一下configparser,个人感觉有点像logging模块中的logger一样
config.read(‘my.cnf‘,encoding=‘utf-8‘)  #读取配置文件,编码类型为utf-8

result = config.sections() #使用sections()方法读取所有section,以列表形式返回
print(result)


#结果
[‘mysqld‘, ‘client‘]
技术分享

(2)获取指定section下所有键值对:items()方法

技术分享
import configparser

config = configparser.ConfigParser()
config.read(‘my.cnf‘,encoding=‘utf-8‘)

#使用items() 方法列出指定section下所有的键值对,返回一个列表的形式,key和value列表中的一个tuple
result = config.items(‘mysqld‘)
print(result)

#结果:
[(‘basedir‘, ‘/usr/local/mysql‘), (‘datadir‘, ‘/data/mysql‘), (‘socket‘, ‘/data/mysql/mysql.sock‘)]
技术分享

(3)获取指定节点下所有的键, 使用options() 方法

技术分享
import configparser

config = configparser.ConfigParser()
config.read(‘my.cnf‘,encoding=‘utf-8‘)

#获取指定section下的所有的键,以列表的形式返回
result = config.options(‘mysqld‘)
print(result)

#结果:
[‘basedir‘, ‘datadir‘, ‘socket‘]
技术分享

(4)获取指定节点下键的值, 使用get() 方法

技术分享
import configparser

config = configparser.ConfigParser()
config.read(‘my.cnf‘,encoding=‘utf-8‘)
#get方法,mysqld节点下socket键
result = config.get(‘mysqld‘,‘socket‘)
print(result)

#执行结果:
/data/mysql/mysql.sock
技术分享

(5)检查、删除、添加特定section,方法has_section(), add_section(), remove_section()

技术分享
import configparser

config = configparser.ConfigParser()
config.read(‘my.cnf‘,encoding=‘utf-8‘)

#检查指定的section是否存在,返回一个布尔值,存在为True
result = config.has_section(‘mysqld‘)

print(result)
#结果: True

#######################################
#添加节点 mysqldump
config.add_section(‘mysqldump‘)
config.write(open(‘my.cnf‘,‘w‘))  #需要使用write方法写入内存数据到配置文件中,不然是不能持久化到文件的
result = config.sections()
print(result)

#执行sections查看添加后结果:
[‘mysqld‘, ‘client‘, ‘mysqldump‘]


#######################################
#删除节点,mysqldump
config.remove_section(‘mysqldump‘)  #使用remove()方法
config.write(open(‘my.cnf‘,‘w‘))  #同样默认是在内存中操作,需要调用write方法,将内存数据写入到文件来持久化存储
result = config.sections()
print(result)

#执行sections查看添加后结果:
[‘mysqld‘, ‘client‘ ]
技术分享

(6) 检查、删除设置section内的key-value

技术分享
#检查section mysqld下的socket键值对是否存在
import configparser

config = configparser.ConfigParser()
config.read(‘my.cnf‘,encoding=‘utf-8‘)
#使用has_option方法,返回一个布尔值,存在为True
result = config.has_option(‘mysqld‘,‘socket‘)
print(result)
#执行结果:
True


#####################################
#在mysqld中添加 键 innodb_file_per_table 值为1
#使用set方法
config.set(‘mysqld‘,‘innodb_file_per_table‘,‘1‘)
config.write(open(‘my.cnf‘,‘w‘))  #同样需要写入内存数据到文件,使用write方法
result = config.options(‘mysqld‘)
print(result)

#执行查看结果:
[‘basedir‘, ‘datadir‘, ‘socket‘, ‘innodb_file_per_table‘]



#####################################
#删除mysqld下的socket键
#使用remove_option()方法
config.remove_option(‘mysqld‘,‘innodb_file_per_table‘)
config.write(open(‘my.cnf‘,‘w‘))  #写入内存数据到文件
result = config.options(‘mysqld‘)
print(result)

#执行查看结果:
[‘basedir‘, ‘datadir‘, ‘socket‘]
技术分享

使用configparser可以方便的对配置文件(ini)进行操作,其实configparser底层也是使用open函数打开文件,然后在此基础上做操作。

2. xml模块

xml在Internet上被广泛的用于数据交换,同时xml也是一种存储应用数据的常用格式。如下xml例子:

技术分享
<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Planet Python</title>
        <link>http://planet.python.org/</link>
        <language>en</language>
        <description>Planet Python - http://planet.python.org/</description>
        <item>
            <title>Steve Holden: Python for Data Analysis</title>
            <guid>http://holdenweb.blogspot.com/...-data-analysis.html</guid>
            <link>http://holdenweb.blogspot.com/...-data-analysis.html</link>
            <description>...</description>
            <pubDate>Mon, 19 Nov 2012 02:13:51 +0000</pubDate>
        </item>
        <item>
            <title>Vasudev Ram: The Python Data model (for v2 and v3)</title>
            <guid>http://jugad2.blogspot.com/...-data-model.html</guid>
            <link>http://jugad2.blogspot.com/...-data-model.html</link>
            <description>...</description>
            <pubDate>Sun, 18 Nov 2012 22:06:47 +0000</pubDate>
        </item>
        <item>
            <title>Python Diary: Been playing around with Object Databases</title>
            <guid>http://www.pythondiary.com/...-object-databases.html</guid>
            <link>http://www.pythondiary.com/...-object-databases.html</link>
            <description>...</description>
            <pubDate>Sun, 18 Nov 2012 20:40:29 +0000</pubDate>
        </item>
        ...
    </channel>
</rss>
技术分享

(1) 解析xml

使用XML() 将字符串解析成xml对象

技术分享
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Author: DBQ(Du Baoqiang)

from xml.etree import ElementTree as ET

#打开文件
result_xml = open(‘example.xml‘,‘r‘).read()
#将字符串解析成xml特殊对象,root指的是xml文件的根节点
root = ET.XML(result_xml)
print(root)
#结果, 返回一个Element对象
<Element ‘rss‘ at 0x1018772c8>
技术分享

使用xml.etree.ElementTree.parse()  函数解析整个xml文件并将其转换成一个文档对象。 

tree = ET.parse(‘example.xml‘)
root = tree.getroot()
print(root)

#执行后结果:
<Element ‘rss‘ at 0x1019772c8>

(2)操作xml

xml格式类型是节点里嵌套节点 ,所以对于每一个节点都有如下的功能:

技术分享 节点功能

遍历xml文档的所有内容:

技术分享 遍历xml文档的所有内容

遍历xml文档中指定的节点:

技术分享 遍历xml文档中指定节点link内容

修改节点的内容

和上面configparser一样,所做的修改是在内存中进行,并不会对xml原始文档做修改,如果需要保存修改的配置,需要将内存里的数据写入到xml文件中。

也是分两种方式,解析字符串方式的修改保存, 和直接解析文件方式的修改,保存。

技术分享 解析字符串方式修改保存
技术分享 解析xml文件方式修改保存

删除节点,删除所有节点下的language

技术分享 解析字符串方式删除节点,保存配置
技术分享 解析xml文件方式删除节点,保存配置

(3) 创建xml文档

技术分享 方式一
技术分享 方式二创建
技术分享 方式三创建

默认保存的xml没有缩进,特别的难看,可以按照下面方式添加缩进:

技术分享 缩进
技术分享 三种创建方式都一样!

(4) 命令空间

技术分享 命名空间

详细介绍

3. shutil模块

shutil是一种高级的文件操作工具,可操作的包括:文件、文件夹、压缩文件的处理。

操作方法:

shutil.copyfileobj(fsrc, fdst, [length=16*1024])  将文件内容拷贝到另外一个文件

import shutil
shutil.copyfileobj(open(‘data.xml‘,‘r‘),open(‘data_new.xml‘,‘w‘))

#将会生成一个data_new.xml文件,内容和data.xml一模一样,有点类似于Shell中的cat data.xml > data_new.xml

shutil.copyfile(src, dst) 直接拷贝文件,如果dst存在的话,会被覆盖掉,谨慎操作。

技术分享
import shutil
import os

shutil.copyfile(‘data.xml‘,‘data_new2.xml‘)

result = os.listdir(os.path.dirname(__file__))
for i in result:
    print(i)
#执行后会在当前目录下生成一个文件
data_new2.xml
技术分享

shutil.copymode(src, dst) 拷贝文件权限,属主、属组和文件内容均不变。

技术分享
#先查看文件权限:
os.system(‘ls -l data.xml‘)
-rw-r--r--  1 daniel  staff  690 Jun 20 19:15 data.xml

#查看data_new2.xml权限
os.system(‘ls -l data_new2.xml‘)
-rw-------  1 daniel  everyone  690 Jun 21 11:40 data_new2.xml

#拷贝权限试试
shutil.copymode(‘data.xml‘,‘data_new2.xml‘)
os.system(‘ls -l data_new2.xml‘)

#结果:权限变成和data.xml一样了,但是属主组这些不变
-rw-r--r--  1 daniel  everyone  690 Jun 21 11:40 data_new2.xml
技术分享

shutil.copystat(src, dst)  拷贝文件状态信息,状态信息包括: atime , mtime, flags, mode bits

技术分享
#先查看下两个文件的状态信息:
print(os.stat(‘data.xml‘))
print(os.stat(‘data_new2.xml‘))
#执行结果:
os.stat_result(st_mode=33188, st_ino=7289084, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=690, st_atime=1466480420, st_mtime=1466421339, st_ctime=1466421339)
os.stat_result(st_mode=33188, st_ino=7295271, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=12, st_size=690, st_atime=1466480420, st_mtime=1466480420, st_ctime=1466480490)


#拷贝状态信息data.xml到data_new2.xml, 可以看到mtime同步了
os.stat_result(st_mode=33188, st_ino=7289084, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=690, st_atime=1466480420, st_mtime=1466421339, st_ctime=1466421339)
os.stat_result(st_mode=33188, st_ino=7295271, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=12, st_size=690, st_atime=1466480420, st_mtime=1466421339, st_ctime=1466480937)
技术分享

shutil.copy(src, dst)  拷贝文件和权限

技术分享
shutil.copy(‘data.xml‘,‘data2.xml‘)

print(os.stat(‘data.xml‘))
print(os.stat(‘data2.xml‘))


#结果:uid,gid, 权限都一样
os.stat_result(st_mode=33188, st_ino=7289084, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=690, st_atime=1466481121, st_mtime=1466421339, st_ctime=1466421339)
os.stat_result(st_mode=33188, st_ino=7295817, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=690, st_atime=1466481121, st_mtime=1466481121, st_ctime=1466481121)
技术分享

shutil.copy2(src, dst)  拷贝文件以及文件的状态信息

技术分享
shutil.copy2(‘data.xml‘,‘data3.xml‘)

print(os.stat(‘data.xml‘))
print(os.stat(‘data3.xml‘))

#执行结果,atime, mtime一样
os.stat_result(st_mode=33188, st_ino=7289084, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=690, st_atime=1466481242, st_mtime=1466421339, st_ctime=1466421339)
os.stat_result(st_mode=33188, st_ino=7295871, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=690, st_atime=1466481242, st_mtime=1466421339, st_ctime=1466481242)
技术分享

shutil.ignore_patters(*patterns)  忽略某匹配模式的文件拷贝,生成一个函数,可以作为调用copytree()的ignore参数。

需要结合shutil.copytree(src , dst,symlinks=False, ignore=None)

技术分享
import shutil
import os
#先看dir1下面有什么文件:
result = os.listdir(‘dir1‘)
for i in result:
    print(i)

__init__.py
company.xml
company_v2.xml
company_v3.xml
data.tar
data.xml
data.zip
data2.xml
data3.xml
data_new
data_new.xml
data_new2.xml
example.xml
example_new.xlm
example_new.xml
example_new2.xml
my.cnf
test_popen
test_popen_2


#那就copy的时候排除xml后缀的文件
shutil.copytree(‘dir1‘,‘dir2‘, ignore=shutil.ignore_patterns(‘*.xml‘))
#注意,目标文件dir2不能存在,否则会报错!
result = os.listdir(‘dir2‘)
for i in result:
    print(i)

#结果:
__init__.py
data.tar
data.zip
data_new
example_new.xlm
my.cnf
test_popen
test_popen_2
技术分享
技术分享
#默认的symlinks为False,如果dir1中有一个软链文件的话test.py:
>>> os.system(‘ls -l dir1‘)
total 4
-rw-r--r-- 1 root root    0 Jun 21 12:09 1.mp3
-rw-r--r-- 1 root root    0 Jun 21 12:09 1.txt
-rw-r--r-- 1 root root    0 Jun 21 12:09 1.xml
drwxr-xr-x 3 root root 4096 Jun 21 13:27 2
-rw-r--r-- 1 root root    0 Jun 21 12:09 2.mp3
-rw-r--r-- 1 root root    0 Jun 21 12:09 2.txt
-rw-r--r-- 1 root root    0 Jun 21 12:09 2.xml
-rw-r--r-- 1 root root    0 Jun 21 12:09 3.mp3
-rw-r--r-- 1 root root    0 Jun 21 12:09 3.txt
-rw-r--r-- 1 root root    0 Jun 21 12:09 3.xml
lrwxrwxrwx 1 root root   12 Jun 21 13:27 test.py -> /tmp/test.py

#默认的拷贝文件夹树
>>> shutil.copytree(‘dir1‘,‘dir2‘,ignore=shutil.ignore_patterns(‘*.xml‘))
‘dir2‘

#查看dir2
>>> os.system(‘ls -l dir2‘)
total 4
-rw-r--r-- 1 root root    0 Jun 21 12:09 1.mp3
-rw-r--r-- 1 root root    0 Jun 21 12:09 1.txt
drwxr-xr-x 3 root root 4096 Jun 21 13:27 2
-rw-r--r-- 1 root root    0 Jun 21 12:09 2.mp3
-rw-r--r-- 1 root root    0 Jun 21 12:09 2.txt
-rw-r--r-- 1 root root    0 Jun 21 12:09 3.mp3
-rw-r--r-- 1 root root    0 Jun 21 12:09 3.txt
-rw-r--r-- 1 root root    0 Jun 16 10:59 test.py   #把软链文件直接复制一份过来了



#使用symlinks参数
>>> shutil.copytree(‘dir1‘,‘dir3‘,symlinks=True,ignore=shutil.ignore_patterns(‘*.xml‘))
‘dir3‘
>>> os.system(‘ls -l dir3‘)
total 4
-rw-r--r-- 1 root root    0 Jun 21 12:09 1.mp3
-rw-r--r-- 1 root root    0 Jun 21 12:09 1.txt
drwxr-xr-x 3 root root 4096 Jun 21 13:27 2
-rw-r--r-- 1 root root    0 Jun 21 12:09 2.mp3
-rw-r--r-- 1 root root    0 Jun 21 12:09 2.txt
-rw-r--r-- 1 root root    0 Jun 21 12:09 3.mp3
-rw-r--r-- 1 root root    0 Jun 21 12:09 3.txt
lrwxrwxrwx 1 root root   12 Jun 21 13:27 test.py -> /tmp/test.py   #软链也带过来了
技术分享

shutil.rmtree(path[, ignore_error[,noerror]])  递归方式删除文件 

>>> shutil.rmtree(‘dir3‘)
>>> os.listdir(‘.‘)
[‘dir2‘, ‘dir1‘] 
#dir3目录已经被删除了

shutil.move(src, dst)  递归方式移动(重命名)文件/文件夹,   和shell中的mv命令一样

技术分享
>>> os.listdir(‘.‘)
[‘dir2‘, ‘dir1‘]
>>> shutil.move(‘dir2‘,‘/tmp/dir_2‘)
‘/tmp/dir_2‘
>>> os.listdir(‘.‘)
[‘dir1‘]
>>> os.listdir(‘/tmp‘)
[‘dir_2‘, ‘test.py‘, ‘1_bak‘, ‘hsperfdata_root‘]
技术分享

shutil.make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0,dry_run=0, owner=None, group=None, logger=None)

创建压缩包并返回文件的路径

base_name:  压缩包名,也可以指定文件存放的绝对路径,如果不指定路径名,压缩包存放在当前路径。

format: 压缩包种类,如 zip, tar, bztar, gztar

root_dir:  要压缩文件/文件夹的路径, 默认当前路径

owner: 属主, 默认当前用户

group:   属组, 默认当前用户组

logger: 记录日志,通常是logging.Logger对象

>>> shutil.make_archive(‘dir1‘,‘gztar‘,base_dir=‘dir1‘)
‘dir1.tar.gz‘
#查看压缩的
>>> os.listdir(‘.‘)
[‘dir1.tar.gz‘, ‘dir1‘]
#指定绝对路径
>>> shutil.make_archive(‘/tmp/dir1‘,‘gztar‘,base_dir=‘dir1‘)
‘/tmp/dir1.tar.gz‘
>>> os.listdir(‘/tmp‘)
[‘dir_2‘, ‘dir1.tar.gz‘, ‘test.py‘, ‘1_bak‘, ‘hsperfdata_root‘]

ZipFile模块是处理zip压缩包的模块,用于压缩和解压,添加和列出压缩包的内容。ZipFile是主要的类,其过程是讲每个文件以及相关的信息作为ZipInfo对象操作到ZipFile的成员,包括文件头信息和文件内容。ZipFile模块详细介绍,点我

tarfile模块可以用于压缩/解压tar类型文件,并且支持进一步压缩tar.gz和tar.bz2文件,主要是调用open函数打开文件,并返回TarFile实例。Tarfile模块详细介绍,点我

其实shutil对压缩包的处理就是调用ZipFile 和 TarFile两个模块来处理的。

技术分享
import zipfile

#压缩
zip_file = zipfile.ZipFile(‘test.zip‘,‘w‘)

zip_file.write(‘s2_xml.py‘)
zip_file.write(‘s3_xml2.py‘)
zip_file.close()
#执行完上面代码后,会发现在当前目录生辰搞一个test.zip文件



#解压缩:
zf = zipfile.ZipFile(‘test.zip‘,‘r‘)
zf.extractall()
zf.close()

#手动删除原有的s2_xml.py s3_xml2.py之后,执行上述代码,而后两个文件又恢复了。。。
技术分享

如果要解压单个文件:

技术分享
#想要解压缩某一个文件,首先要知道压缩包内包含什么文件。
zf = zipfile.ZipFile(‘test.zip‘,‘r‘)
#先使用namelist()方法来查看压缩包内的文件,返回一个列表的形式
result = zf.namelist()
for i in result:
    print(i)

#for循环,查看执行结果:
s2_xml.py
s3_xml2.py

#解压s2_xml.py出来,先删除当前目录下的这个文件:
#而后使用extract()方法解压
zf.extract(‘s2_xml.py‘)
技术分享

tarfile

技术分享
import tarfile

#打包

tar_file = tarfile.open(‘test.tar‘,‘w‘)
tar_file.add(‘s3_xml2.py‘,arcname=‘s3_xml2.py‘)
tar_file.add(‘s4_xml.py‘,arcname=‘wobugaosuni.py‘)
tar_file.close()

#arcname是在包里的文件名字,打包后的文件名字可以和源文件名字不同

#删除原有两个文件,而后解压
tar_file = tarfile.open(‘test.tar‘,‘r‘)
tar_file.extractall()
tar_file.close()

#注意上面的s4_xml.py在压缩包内的名字是wobugaosuni.py, 解压后的文件,也是这个名字
技术分享
技术分享
#解压归档包里的某一个文件,还是首先要查看包里包含什么文件。使用getnames()方法,返回一个列表,而后使用extract()解压所需的单个文件
tar_file = tarfile.open(‘test.tar‘,‘r‘)

tar_file.extract(‘s3_xml2.py‘)

tar_file.close()
技术分享

4. subprocess模块

subprecess模块允许你产生新的进程,然后连接他们的输入、输出、错误管道,并获取返回值。

启动一个子进程的方式是使用便捷函数。对于更高级的使用场景当便捷函数不能满足需求是,可以使用底层的Popen接口。

subprocess.call(args, * , stdin=None, stdout=None, stderr=None,shell=False) 执行args命令,等待命令完成,然后返回状态码。

技术分享
import subprocess

result = subprocess.call([‘ls‘,‘-l‘])  #默认shell为False,传入命令带参数的时候也是需要使用列表元素来传入。
print(result)
#可将shell 置为True,使用和shell下一样的方式:
result = subprocess.call(‘ls -l‘,shell=True)
print(result)
技术分享

subprocess.check_call(args, *, stdin=None,stdout=None,stderr=None,shell=False)执行带参数的命令,等待命令完成,如果状态码是0则返回0,否则则抛出CalleProcessError的异常。

技术分享
result = subprocess.check_call(‘ls -l‘,shell=True)
#正常执行后返回执行结果
print(result)

#执行一个不存在的命令,则抛出异常:
result1 = subprocess.check_call(‘sb‘,shell=True)
print(result1)

.....
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command ‘sb‘ returned non-zero exit status 127
技术分享

subprocess.check_output(args, *, stdin=None,stdout=None,stderr=None,shell=False,universal_newlines=False)

执行带参数的命令并将它的输出作为字字节字符串返回。如果返回值非0,抛出异常CalledProcessError。

技术分享
>>> subprocess.check_output([‘ls‘,‘-l‘])
b‘total 8\\ndrwxr-xr-x 3 root root 4096 Jun 21 13:27 dir1\\n-rw-r--r-- 1 root root  276 Jun 21 13:55 dir1.tar.gz\\n‘

#返回非0,抛异常
>>> subprocess.check_output([‘ls‘,‘-l‘,‘/sb‘])
ls: cannot access /sb: No such file or directory
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.4/subprocess.py", line 620, in check_output
    raise CalledProcessError(retcode, process.args, output=output)
subprocess.CalledProcessError: Command ‘[‘ls‘, ‘-l‘, ‘/sb‘]‘ returned non-zero exit status 2
技术分享

subprocess.Popen()  Popen构造函数接受大量可选参数。对于大部分典型的使用场景,这些参数中的许多个可以安全的保持为默认值。常用参数:

  • args:  shell执行命令,默认shell为False,传入的args必须是序列类型数据,如元组或列表。
  • bufsize: 指定缓冲,0为无,1按行缓冲,其它的正数表示使用缓冲区的大小,负值表示使用系统缓冲的默认值,通常表示完全缓存,默认值为0。
  • stdin, stdout, stderr: 分别指定程序的标准输入、标准输出、标准错误的文件句柄。合法的值有PIPE、一个已经存在的文件描述符(一个正整数)、一个已经存在的文件对象和None。PIPE表示应该为子进程创建一个新的管道。如果默认设置None,则不会发生重定向;子进程的文件句柄从父进程继承。另, stderr可以为STDOUT, 它表示来自子进程中标准错误的数据应该被捕获到标准输出相同的文件中。
  • shell:默认为False,指定是否使用shell来执行程序。如果为真,则建议传递一个字符串,而不是一个序列。
  • preexec_fn :如果设定为一个可调用对象,该对象将在子进程中在子进程执行之前调用。(只在*nix上)
  • close_fn : 如果为真,所有的描述符除了0,1,和2之外将在执行子进程之前关闭(只在*nix上)。在windows上为真,那么子进程不会继承任何句柄。注意在windows上你不可以设置close_fds为真并同时设置stdin、stdout或者stderr重定向标准句柄。
  • cwd: 如果不为None,那么子进程当前目录在其执行之前将改变为cwd。注意在搜索可执行程序时,该目录不会考虑在内,所以你不可以指定相对cwd的程序路径。
  • env: 如果不为None,它必须是一个定义了新进程环境变量的映射,这些环境变量将被使用而不是继承当前进程的环境这种默认的行为。
  • eniversal_newlines:  如果为真, 那么文件对象stdout和stderr作为文本文件以universal newlines模式打开。每一行的终止符可能是*nix风格的‘\\n‘, 旧时的Macintosh风格的‘\\r‘ 或者windows的‘\\r\\n‘. 所有这些外部的表示在Python程序看来都是‘\\n‘。
  • startupinfo: 如果给出,将是一个STARTUPINFO对象, 它将传递给底层CreateProcess函数。creationflags如果给出,可以是CREATE_NEW_CONSOLE或者CREATE_NEW_PROCESS_GROUP。(只在windows上)

输入python3,进入解释器,然后输出一个hello world

技术分享
import subprocess

#将标准输入、输出、错误使用PIPE管道
obj = subprocess.Popen(‘Python‘,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,universal_newlines=True)

#而后写入stdin
obj.stdin.write(‘print("hello world")\\n‘)
obj.stdin.write(‘print("hello world agin")\\n‘)
obj.stdin.close()

#读取标准输出,而后关闭
out = obj.stdout.read()
obj.stdout.close()

#读取标准错误,而后关闭
err = obj.stderr.read()
obj.stderr.close()

#打印
print(out)
print(err)

 

 

技术分享

 

技术分享

 

技术分享

以上是关于day7的主要内容,如果未能解决你的问题,请参考以下文章

学习python:day7

DAY7

day7

LeetCode刷题笔记-动态规划-day7

LeetCode刷题笔记-动态规划-day7

LeetCode刷题笔记-动态规划-day7