subprocess模块
铺垫:
1、os模块
os模块中的system,使用os.system("dir")可直接输出结果,如果将os.system("dir")赋值给一个变量,则这个变量接收的是这个命令执行成功与否,如果非0则执行不成功,0表示执行成功。
a=os.popen("dir").read()会保存命令输出结果,并赋值给a,此时print(a)就可以输出到屏幕
2、commands模块:只使用于linux
正题:
subprocess.run(['df','-h'])
涉及到管道符的时候,subprocess.run('df -h | grp sda1',shell=True)
subprocess.getstatusoutput('ls /bin/ls')接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结果即(0,'/bin/ls')
其它方法如getoutput、check_output、check_call等不经常使用
以上方法,底层都是封装的subprocess.Popen
例1:res=subprocess.Popen("ifconfig |grep 192",shell=Ture,stdout=subprocess.PIPE)此时是把命令执行结果保存在内存空间的管道中,如果想输出到屏幕需要用res.stdout.read(),这里存在命令输入错误报错的情况,如果报错会把错误直接输入到屏幕上,管道中为空。如要保存错误信息,需增加stderr=subprocess.PIPE字段,此时把错误信息也保存到了管道中。
例2:poll()和wait()方法
在例1中如果命令执行耗时很长,如:res=subprocess.Popen("sleep 10;echo 'hello'",shell=Ture,stdout=subprocess.PIPE,stderr=subprocess.PIPE),当使用res.stdout.read()时会等待命令执行结束才能显示,而poll方法可检测命令是否执行结束,0表示执行结束,在编程时可与read结合使用,优化程序。同样wait方法也是要等待程序执行。
例3:terminate()
该方法可以中断执行,如:res=subprocess.Popen("sleep 10;echo 'hello'",shell=Ture,stdout=subprocess.PIPE,stderr=subprocess.PIPE)本需要10s才能执行完,并可以通过res.stdout.read()输出到屏幕,如果中途使用res.terminate(),再调用read方法则为空。
可用参数:
- args:shell命令,可以是字符串或者序列类型
- cwd:用于设置子进程的当前目录
- stdin,stdout,stderr:分别表示程序的标准输入、输出、错误句柄
- env:用于指定子进程的环境变量。如果env=None,子进程的环境变量将从父进程中继承
面向对象
概念
OOP(object oriented programing)编程就是利用类和对象来创建各种模型来实现对真实世界的描述,面向对象编程可以使程序的维护和扩展更简单,提高开发效率。
核心特性
- Class类:对一类相同属性的抽象集合。
- Object对象:一个类的实例化后的实例,即调用类生成的实体。
- Encapsulation封装:在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法。之所以要封装是防止数据被随意修改,并使外部程序方便快捷的调用,而无需关注内部构造。
- Inheritance继承:一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承。
- Polymorphism多态:一个接口,多种实现。指一个基类中派生了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。
类的定义
class dog(object):
def __init__(self,name,food): #构造函数
self.NAME = name
self.FOOD = food
def sayhi(self):
print("Hi,i am a dog,my name is %s" %self.NAME)
def eat(self):
print("I like eat %s" %self.FOOD)
d1 = dog('Sanmao','apple')
d2 = dog('lisi','banana')
print(d1.NAME)
d2.sayhi()
d1.eat()
d2.eat()
继承
被继承的类称为“基类”
代码示例:
class Person(object):
def talk(self):
print("会说话")
class chinaperson(Person):
def walk(self):
print("会走路")
a = chinaperson()#实例a同时具有自己定义的属性walk和从基类中继承的属性talk
a.talk()
a.walk()
具体应用:学校实例
import time
class ShoolMember(object):
member = 0
def __init__(self,name,age,sex):#构造函数
self.name = name
self.age = age
self.sex = sex
self.enroll()
def enroll(self):
'''注册'''
print('enroll a new member',self.name)
ShoolMember.member += 1
def tell(self):
print('--------------info %s----------------'%self.name)
for a,v in self.__dict__.items():
print('\t',a,v)
def __del__(self):#析构函数,在程序运行结束后自动执行,手动删除s2,运行结束后自动删除t1和s1
print('开除了',self.name)
ShoolMember.member -=1
class Teacher(ShoolMember):
def __init__(self,name,age,sex,salary,course):#先继承,再重构
ShoolMember.__init__(self,name,age,sex) #经典类写法
#super(Teacher,self).__init__(name,age,sex)新式类写法
self.salary = salary
self.course = course
def teaching(self):
print('%s is teaching %s'%(self.name,self.course))
class Student(ShoolMember):
def __init__(self,name,age,sex,course,tuition):
ShoolMember.__init__(self,name,age,sex)
self.course = course
self.tuition =tuition
def study(self):
print('%s is studing %s,course is %s'%(self.name,self.course,self.tuition))
t1 = Teacher('zhangsan',30,'F',30000,'python')
s1 = Student('lisi',24,'M','python',11000)
s2 = Student('wangwu',18,'M','python',11000)
#print(s1.__dict__)使用该方法可以获取实例的所有参数,即可在tell函数中使用该方法
t1.tell()
s1.tell()
print('学校总人数',ShoolMember.member)
del s2
print('学校总人数',ShoolMember.member)
time.sleep(5)
# t1.teaching()
# s1.study()
经典类与新式类
class A(object):
def __init__(self):
self.n = 'A'
class B(A):
pass
# def __init__(self):
# self.n = 'B'
class C(A):
def __init__(self):
self.n = 'C'
class D(B,C):
pass
# def __init__(self):
# self.n = 'D'
'''
D继承B、C,B、C继承A
正常情况下print(D().n)输出的是D
如果class D修改成pass,输出的是B
如果class B修改成pass,输出的是C
如果class C修改成pass,输出的是A
此查询方法称之为广度查询,即先查询同级的B、C,都查不到的情况下才查上级A
以上方法为新式类写法
如果把class A修改为经典类写法,其它保持不变,并在python2环境中运行(在python3环境中也遵循广度查询法)
class A:
def __init__(self):
self.n = 'A'
则遵循深度查询
'''
print(D().n)