Subprocess
1.run方法(Python3.5开始才有)
>>> subprocess.run(["ls","-l"])
total 21772
-rw-------. 1 root root 1623 Mar 8 2017 anaconda-ks.cfg
-rw-r--r-- 1 root root 19026 Mar 8 14:33 auto7.py
-rw-r--r-- 1 root root 5 Mar 8 16:13 nic_name_temp
drwxr--r-- 18 501 games 4096 Mar 8 14:44 Python-3.6.0
-rw-r--r-- 1 root root 22256403 Dec 23 10:24 Python-3.6.0.tgz
-rw-r--r-- 1 root root 1879 Mar 8 14:33 yum.py
CompletedProcess(args=['ls', '-l'], returncode=0)
注:每个参数都必须作为一个列表的值传入
2.shell=True
>>> subprocess.run("df -Th",shell=True)
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/cl-root xfs 96G 2.0G 94G 2% /
devtmpfs devtmpfs 982M 0 982M 0% /dev
tmpfs tmpfs 993M 0 993M 0% /dev/shm
tmpfs tmpfs 993M 8.6M 984M 1% /run
tmpfs tmpfs 993M 0 993M 0% /sys/fs/cgroup
/dev/sda1 xfs 197M 128M 70M 65% /boot
tmpfs tmpfs 199M 0 199M 0% /run/user/0
CompletedProcess(args='df -Th', returncode=0)
注:如果碰到复杂的命令,比如涉及到’|’管道符的,那么Python是没办法处理的,这时需要使用shell=True,意思是直接将整段命令作为字符串推送给shell bash做直接的处理,不经过Python
3.3.5之前shell命令返回结果的问题
>>> subprocess.getstatusoutput("cat /etc/passwd |grep root")
(0, 'root:x:0:0:root:/root:/bin/bash\noperator:x:11:0:operator:/root:/sbin/nologin')
注:以元组的方式返回命令的执行成功与否以及执行过程
4.Popen.stdout
>>> res = subprocess.Popen("ifconfig |grep 10.0",shell=True,stdout=subprocess.PIPE)
>>> res.stdout.read()
b' inet 10.0.0.14 netmask 255.255.255.0 broadcast 10.0.0.255\n ether 00:0c:29:89:a4:21 txqueuelen 1000 (Ethernet)\n'
注:上面那条命令只是封装了底层的POPEN,需要注意的是POPEN需要定义命令的标准输出,PIPE的意思是管道,需要将命令的执行结果放进管道里面(管道相当于在内存中开辟了一段新地址,用来放执行结果),然后再通过管道进行输出到屏幕上,相当于高级一点的.run方法
5.Popen.stderr
>>> res = subprocess.Popen("ifconfigssss |grep 10.0",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> res.stdout.read()
b''
>>> res.stderr.read()
b'/bin/sh: ifconfigssss: command not found\n'
注:同时还可以定义错误输出,通过正确的输出以及错误的输出智能选择是否输出到屏幕上
6.poll,wait
>>> res = subprocess.Popen("sleep 10;ls",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> res.wait()
0
>>>
>>>
>>>
>>> res = subprocess.Popen("sleep 10;ls",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> res.poll()
>>>
>>> res.poll()
>>> res.poll()
>>> res.poll()
0
注:如果执行一条命令需要的时间非常长,使用上文举出的方法就有可能不合适,因为如果当前终端因为故障原因退出了就会导致命令执行失败,使用poll就是允许检查程序执行过程,如果没有执行完就没有返回结果,如果0也就是执行结束了,wait的效果则是一直等待命令执行结束,否则一直卡着在屏幕上
7.terminate
>>> res.terminate()
注:将res命令的进程直接中断
8.cwd参数
>>> res = subprocess.Popen("pwd",shell=True,cwd="/home",stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> res.stdout.read()
b'/home\n'
注:设置执行命令的默认目录
面向对象
1.类、实例化、对象
#!/usr/bin/env python3
# this is CR7 scripts!
class dog(object):
def saihi(self):
print("Wow wow~~~")
d1 = dog()
d1.saihi()
###############################
Wow wow~~~
注:定义最简单的面向对象的函数,首先实例化对象,然后通过对象调用方法
类封装:在类中对数据的赋值,内部调用外语外部是透明的,防止数据被恶意修改
2.多重实例化
#!/usr/bin/env python3
# this is CR7 scripts!
class dog(object):
def saihi(self):
print("Wow wow~~~")
d1 = dog()
d2 = dog()
d1.saihi()
d2.saihi()
###################################
Wow wow~~~
Wow wow~~~
注:问题所在,通过输出并不能看出谁是谁,到底哪儿条狗是哪儿条狗?
3.定义构造函数(初始化变量,也叫类中的全局变量)
#!/usr/bin/env python3
# this is CR7 scripts!
class dog(object):
def __init__(self,name):
self.NAME = name
def saihi(self):
print("Wow wow~~~ i am",self.NAME)
d1 = dog("d1")
d2 = dog("d2")
d1.saihi()
d2.saihi()
##############################################
Wow wow~~~ i am d1
Wow wow~~~ i am d2
注:如果需要知道哪儿条狗是哪儿条狗,那么需要定义参数传入自己的名字,这时就需要使用__init函数,需要注意的是:
1.d1 = dog(“d1”) 相当于 dog(d1,”d1”)
即把实例对象d1自己作为参数传给self,”d1”名字传给__init中的name变量,也就得出self.NAME = d1.NAME = name
2.d1.saihi() 相当于 saihi(d1)
同样把d1自己作为参数传给saihi(self)中,也就是self = d1,又由于self.NAME的值已经在之前赋值过,所以可以得出结果,self存在的意义就是为了解决函数和函数之间局部变量不能互相通信所带来的问题,也是为了解决方法和方法之间打通信息交互的渠道而存在的
4.定义额外的方法设置局部变量
#!/usr/bin/env python3
# this is CR7 scripts!
class dog(object):
def __init__(self,name):
self.NAME = name
def saihi(self):
print("Wow wow~~~ i am",self.NAME)
def attack(self,attacknum):
print("i am %s,i attack num is %s"%(self.NAME,attacknum))
d1 = dog("d1")
d2 = dog("d2")
d1.saihi()
d2.saihi()
d2.attack(1000)
###################################################
Wow wow~~~ i am d1
Wow wow~~~ i am d2
i am d2,i attack num is 1000
注:和上文不同,此时的attacknum不是作为默认参数在self中定义的,而是作为attack方法中自己定义的,需要被对象调用时传入参数,可提供选择,而且attacknum的值只能被attack方法调用,无法被sayhi方法获取到值,salf.NAME也叫作成员变量,也叫成员属性
5.定义私有属性
#!/usr/bin/env python3
# this is CR7 scripts!
class dog(object):
def __init__(self,name):
self.NAME = name
self.__SEX = "boy and girl"
def show_sex(self):
return self.__SEX
def saihi(self):
print("Wow wow~~~ i am",self.NAME)
print(self.__SEX)
def attack(self,attacknum):
print("i am %s,i attack num is %s"%(self.NAME,attacknum))
d1 = dog("Jack")
print(d1.show_sex())
d1.saihi()
print(d1._dog__SEX)
###################################################
boy and girl
Wow wow~~~ i am Jack
boy and girl
boy and girl
注:__xxx叫作私有属性的值,只能被同一个类中的其他方法(函数)调用,不能被外界去调用,而且不允许修改,如果需要被外界访问,要么定义一个返回值的函数,要么如上强制访问,但是不建议这么做
6.定义公有属性
#!/usr/bin/env python3
# this is CR7 scripts!
class dog(object):
nationality = "China"
def __init__(self,name):
self.NAME = name
self.__SEX = "boy and girl"
def show_sex(self):
return self.__SEX
def saihi(self):
print("Wow wow~~~ i am",self.NAME)
print(self.__SEX)
def attack(self,attacknum):
print("i am %s,i attack num is %s"%(self.NAME,attacknum))
d1 = dog("CR7")
d2 = dog("T9")
print(d1.nationality)
print(d2.nationality)
dog.nationality = "US"
print(d1.nationality)
print(d2.nationality)
d2.nationality = "GUANGDONG"
print(d1.nationality)
print(d2.nationality)
########################################
China
China
US
US
US
GUANGDONG
注:注意每个对象调用方法name等值都是属于对象自己才能访问的“成员属性”,但是这种变量又不是私有属性,而公有属性则是需要定义在类下面,能被所有属于这个类的对象访问的变量才能被称为公有属性,公有属性的值如果被dog.nationality这种方式修改就是全局修改,如果是d1.nationality这种方式的话就是修改自己的,值得注意的是如果d1.nationality这种方式进行了赋值,那么在print的时候相当于把公有属性的nationality赋值一份在自己的方法里,所以d1.nationality修改值了输出并不会影响d2.的调用nationality,如果本地没有nationality,那么引用公有的,如果有,就复制一份到本地的方法
7.析构函数
#!/usr/bin/env python3
# this is CR7 scripts!
class dog(object):
nationality = "China"
def __init__(self,name):
self.NAME = name
self.__SEX = "boy and girl"
def __del__(self):
print("...run...finished...")
def saihi(self):
print("Wow wow~~~ i am",self.NAME)
print(self.__SEX)
def attack(self,attacknum):
print("i am %s,i attack num is %s"%(self.NAME,attacknum))
d1 = dog("CR7")
d2 = dog("T9")
del d1
import time
time.sleep(5)
print("after del...")
#################################################
...run...finished...
after del...
...run...finished...
注:析构函数的作用当实例‘销毁’的时候自动执行的方法,但是如同例子,当del d1时虽然此时程序还在执行sleep方法,还没有结束的时候第一个实例的析构函数已经执行了,为什么呢?因为del删除d1“门牌号”的时候,这个实例就已经结束了,所以即使程序没有结束也会执行析构函数
类继承:父类和子类之间应该是‘属于’关系,子类继承了父类的方法,且可以重构方法
1.类继承调用方法
#!/usr/bin/env python3
# this is CR7 scripts!
class father():
def saihi(self):
print("hello!")
class son(father):
def walk(self):
print("i am walking...!")
d = son()
d.saihi()
d.walk()
######################################
hello!
i am walking...!
注:子类继承父类,可以直接调用父类的方法,当然子类可以自己定义自己的方法,并不会有什么冲突以及造成什么影响
2.子类重写方法
#!/usr/bin/env python3
# this is CR7 scripts!
class father():
def saihi(self):
print("hello!")
class son(father):
def saihi(self):
print("sory about that!")
def walk(self):
print("i am walking...!")
d = son()
d.saihi()
d.walk()
####################################
sory about that!
i am walking...!
注:子类可以修改父类的方法然后调用
3.子类继承构造函数
#!/usr/bin/env python3
# this is CR7 scripts!
class father():
def __init__(self,name,age):
self.NAME = name
self.AGE = age
def saihi(self):
print("hello!")
class son(father):
def saihi(self):
print("sory about that!",self.NAME,self.AGE)
def walk(self):
print("i am walking...!")
d = son("CR7",32)
d.saihi()
d.walk()
##########################################################
sory about that! CR7 32
i am walking...!
4.子类继承重构父类构造函数
#!/usr/bin/env python3
# this is CR7 scripts!
class father():
def __init__(self,name,age):
self.NAME = name
self.AGE = age
self.sex = "boy and girl"
def saihi(self):
print("hello",self.NAME,self.AGE)
class son(father):
def __init__(self,name,age,strength):
father.__init__(self,name,age)
print("My name is %s,my age is %s,i am so %s"%(self.NAME,self.AGE,strength))
print(self.sex)
def saihi(self):
print("sory about that!",self.NAME,self.AGE)
def walk(self):
print("i am walking...!")
class daughter(father):
pass
d1 = son("Charlie",21,10000)
d2 = daughter("Sally",20)
d1.saihi()
d2.saihi()
#######################################
My name is Charlie,my age is 21,i am so 10000
boy and girl
sory about that! Charlie 21
hello Sally 20
注:有两个实例d1和d2,两个实例对应的对象都是继承了父类,d1的实例想继承以及重构父类的构造函数怎么做呢?
1.首先需要继承父类的构造函数,默认什么都不写本身就已经继承了,现在还要重构:
def init(self,name,age,strength):
这里相当于是继承的同时重构了父类构造函数的变量,新添加了strength变量
2.father.init(self,name,age)
继承了重构了构造函数后,需要传值,怎么传值?在此处直接调用了父类的构造函数,son类的对象实例化d1启动时进行了几个值的传值
2.1 self = d1 传值给def中的self,因为此时在son类看来有定义了自己的构造函数,所以没有继承父类的构造函数
2.2 name = Charlie 传值给def中的name
2.3 age = 21 传值给def中的age
2.4 strength 传值给def中的strength
3.四个值都传入之后,再把前三个值传给父类构造函数,然后跳转到父类构造函数进行对应变量的赋值(这就是做到重构的基础上不影响原有变量的继承以及赋值调用),然后执行print语句,这就是重构增加的语句,又由于构造函数不需要调用会自动执行,所以就会有输出信息
5.面向对象联系函数
#!/usr/bin/env python3
# this is CR7 scripts!
class SchoolMember(object):
encoll_number = 0
def __init__(self,name,age,sex):
self.NAME = name
self.AGE = age
self.SEX = sex
self.enroll()
SchoolMember.encoll_number+=1
def enroll(self):
print("[%s] is enroll!"% self.NAME)
def tell(self):
for k,v in self.__dict__.items():
print("\t",k,v)
def __del__(self):
print("%s is delete!"% self.NAME)
SchoolMember.encoll_number-=1
class Teacher(SchoolMember):
def __init__(self,name,age,sex,salary,course):
SchoolMember.__init__(self,name,age,sex)
self.SALARY = salary
self.COURSE = course
def study_course(self):
print("%s 's salary is %s,the course is %s"%(self.NAME,self.SALARY,self.COURSE))
class Student(SchoolMember):
def __init__(self,name,age,sex,fee):
SchoolMember.__init__(self,name,age,sex)
self.FEE = fee
def student_course(self):
print("the student is %s,his fee is %s"%(self.NAME,self.FEE))
t1 = Teacher("tea1",39,"M",100000,"IT")
r1 = Student("stu1",21,"M",5000)
r2 = Student("stu2",12,"WM",3000)
print(SchoolMember.encoll_number)
t1.study_course()
r1.student_course()
print("\n")
t1.tell()
print("\n")
r1.tell()
print("\n")
r2.tell()
del r1
print(SchoolMember.encoll_number)
#######################################################
[tea1] is enroll!
[stu1] is enroll!
[stu2] is enroll!
3
tea1 's salary is 100000,the course is IT
the student is stu1,his fee is 5000
NAME tea1
AGE 39
SEX M
SALARY 100000
COURSE IT
NAME stu1
AGE 21
SEX M
FEE 5000
NAME stu2
AGE 12
SEX WM
FEE 3000
stu1 is delete!
2
tea1 is delete!
stu2 is delete!
6.新式类和经典类
SchoolMember.__init__(self,name,age,sex)
super(Teacher,self).__init__(name,age,sex)
注:效果都是一样的,前者是经典类后者是新式类
7.对象多态实例化
#!/usr/bin/env python3
# this is CR7 scripts!
class ANIMAL(object):
def __init__(self,name):
self.NAME = name
def talk(self):
raise NotADirectoryError("Your must change this func!")
class DOG(ANIMAL):
def talk(self):
print("wang")
class CAT(ANIMAL):
def talk(self):
print("miao~~")
d1 = DOG("china dog")
c1 = CAT("china cat")
def animal(obj):
obj.talk()
animal(d1)
animal(c1)
####################################################################
wang
miao~~
注:Python默认不支持对象实例的多态化,但是可以间接实现,也就是实例调用提供共同的接口,但是又可以根据实例的不通调用不用的方法(方法名字同名)但是又不用关注对象实例名,这种应用场景
组合:
8.静态方法
#!/usr/bin/env python3
# this is CR7 scripts!
class hello(object):
def hello_world(self):
print("alex")
class hello2(object):
@staticmethod
def hello_world2():
print("alex")
h1 = hello()
h1.hello_world()
hello2.hello_world2()
#################################
alex
alex
9.继承复习:
#!/usr/bin/env python3
# this is CR7 scripts!
class F1:
def __init__(self):
print("F1")
def a1(self):
print("F1a1")
def a2(self):
print("f1a2")
class F2(F1):
def __init__(self):
print("F2")
def a1(self):
self.a2()
print("F2a111111111111")
def a2(self):
print("f2a2")
class F3(F2):
def __init__(self):
print("F3")
def a2(self):
print("f3a2222222222222222222222")
obj = F3()
obj.a1()
#################################################
F3
f3a2222222222222222222222
F2a111111111111
注:注意程序处理的流程;
1,首先obj是F3类实例化出来的一个对象,也就意味着F3类中的self等于obj
2,F3类中没有a1这个方法,所以会从父类中去找(由于继承的关系)
3,F2类中有a1的方法,其中会发现执行语句self.a2(),需要注意的是,self的意思始终都是调用当前方法的对象,当前调用方法的对象始终都是obj,也就是说self.a2()会跳转回F3类中的a2,所以会执行f3a2222222222222222222222然后回到执行语句执行下面的F2a111111111111
10.封装复习
#!/usr/bin/env python3
# this is CR7 scripts!
class F1:
def __init__(self,n):
self.N = n
print('F1')
class F2:
def __init__(self,arg1):
self.A = arg1
print("F2")
class F3:
def __init__(self,arg2):
self.B = arg2
print('F3')
o1 = F1('alex')
o2 = F2(o1)
o3 = F3(o2)
#######输出alex##########
# o3 = F3(o2) == o3.b == o2
# o2 = F2(o1) == o2.a == o1
# o3.b.a == o1
# o1 = F1('alex') == o1.n == 'alex'
# o3.b.a.n == 'alex'
#############################################################
F1
F2
F3
注:如图所示,方法里面也可以封装方法(嵌套封装)
11.变量的存放
属性:
1.成员属性(保存在对象中)
2.公有属性(保存在类中)
封装:类中封装了公有属性和方法,对象中封装了成员属性,同时对象中也同时能多层嵌套封装对象:
#!/usr/bin/env python3
# this is CR7 scripts!
class F1(object):
def __init__(self,n):
self.N = n
class F2(object):
def __init__(self,arg1):
self.a = arg1
class F3(object):
def __init__(self,arg2):
self.b = arg2
o1 = F1('alex')
o2 = F2(o1)
o3 = F3(o2)
print(o3.b.a.N)
#################################
alex
注:对象和对象之间形成了连接的关系
继承:
#!/usr/bin/env python3
# this is CR7 scripts!
class F1(object):
def __init__(self):
print("a1")
def a1(self):
print("f1a1")
def a2(self):
print("f1a2")
def a3(self):
print("f1a3")
class F2(F1):
def __init__(self):
print("a2")
def a1(self):
self.a2()
self.a3()
print("f2a1")
def a2(self):
print("f2a2")
class F3(F2):
def __init__(self):
print("a3")
def a2(self):
print("f3a2")
obj = F3()
obj.a1()
###############################
a3
f3a2
f1a3
f2a1
注:执行obj.a1()的时候,第一步查找肯定是去当前对象方法中去找,那么如果没有就去父类中去找,很显然父类有方法a1,但是发现有一条语句self.a2(),始终记得self代指的调用当前方法的对象,也就是相当于obj(F3).a2(),所以执行了f3a2,然后回到父类方法a1中的下面的语句f2a1,当在父类中执行self会重新回到最底层的类然后重新网上找,无限轮训的方式进行self的值的查找
方法:
1.方法(普通的def定义的方法)(保存在类中,被对象调用)
#!/usr/bin/env python3
# this is CR7 scripts!
class test(object):
def hello(self):
print("hello,world!")
obj = test()
obj.hello()
#################################
hello,world!
注:如果没有往对象中传值,那么会白白浪费占用的内存空间
2.静态方法(保存在类中,调用者是类,无须创建对象,可以有任意个参数,但是Python不强制让你做什么)
#!/usr/bin/env python3
# this is CR7 scripts!
class F1:
def a1(self):
print("yes")
obj = F1()
obj.a1()
##########################
注:这种面向的函数并没有往类中去传值,当类中的方法和类没有任何联系的时候,Python也会默认往self中去传值,但是这么写函数会浪费内存空间,也会也会对象本身也会占用内存地址,建议修改成:
#!/usr/bin/env python3
# this is CR7 scripts!
class F1:
@staticmethod
def a1():
print("yes")
F1.a1()
注:静态方法类似面向过程函数