第2部分:Python 面向对象
1、类与对象
1.1 定义类 通常你需要在单独的文件中定义一个类 [root@hadron python]# vi Employee.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
#定义类
class Employee:
'所有员工的基类' #类文档字符串
#类变量
empCount = 0
#类的构造函数或初始化方法,name和salary为实例变量
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print "Total Employee %d" % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
#操作属性
setattr(emp1, 'salary',8000)
print getattr(emp1, 'salary')
print "Total Employee %d" % Employee.empCount
[root@hadron python]# python Employee.py Name : Zara , Salary: 2000 Name : Manni , Salary: 5000 8000 Total Employee 2 1.2 Python内置类属性 __dict__ : 类的属性(包含一个字典,由类的数据属性组成) __doc__ :类的文档字符串 __name__: 类名 __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod) __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组) 对象销毁(垃圾回收) Python 使用了引用计数这一简单技术来跟踪和回收垃圾。 在 Python 内部记录着所有使用中的对象各有多少引用。 一个内部跟踪变量,称为一个引用计数器。 当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为0 时, 它被垃圾回收。 但是回收不是"立即"的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。 垃圾回收机制不仅针对引用计数为0的对象,同样也可以处理循环引用的情况。循环引用指的是,两个对象相互引用,但是没有其他变量引用他们。这种情况下,仅使用引用计数是不够的。Python 的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。作为引用计数的补充, 垃圾收集器也会留心被分配的总量很大(及未通过引用计数销毁的那些)的对象。 在这种情况下, 解释器会暂停下来, 试图清理所有未引用的循环。 析构函数 __del__ [root@hadron python]# vi Point.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Point:
def __init__( self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print class_name, "销毁"
pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # 打印对象的id
del pt1
del pt2
del pt3
[root@hadron python]# python Point.py 140262137177296 140262137177296 140262137177296 Point 销毁 2、类的继承 基类名写在括号里,基本类是在类定义的时候,在元组之中指明的。如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。 1)在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。 2)在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数 3)Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。 [root@hadron python]# vi Parent.py #!/usr/bin/python # -*- coding: UTF-8 -*- class Parent: # 定义父类 parentAttr = 100 def __init__(self): print "调用父类构造函数" def parentMethod(self): print '调用父类方法' def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print "父类属性 :", Parent.parentAttr class Child(Parent): # 定义子类 def __init__(self): print "调用子类构造方法" def childMethod(self): print '调用子类方法 child method' c = Child() # 实例化子类 c.childMethod() # 调用子类的方法 c.parentMethod() # 调用父类方法 c.setAttr(200) # 再次调用父类的方法 c.getAttr() # 再次调用父类的方法 [root@hadron python]# python Parent.py 调用子类构造方法 调用子类方法 child method 调用父类方法 父类属性 : 200 方法重写 [root@hadron python]# vi override.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Parent: # 定义父类
def myMethod(self):
print '调用父类方法'
class Child(Parent): # 定义子类
def myMethod(self):
print '调用子类方法'
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
[root@hadron python]# python override.py 调用子类方法 基础重载方法 1) __init__ ( self [,args...] ),构造函数,简单的调用方法: obj = className(args) 2) __del__( self ),析构方法, 删除一个对象,简单的调用方法 : dell obj 3) __repr__( self ),转化为供解释器读取的形式,简单的调用方法 : repr(obj) 4) __str__( self ),用于将值转化为适于人阅读的形式,简单的调用方法 : str(obj) 5)__cmp__ ( self, x ),对象比较,简单的调用方法 : cmp(obj, x) [root@hadron python]# vi Vector.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)
def __cmp__(self,x):
if self.a>x.a and self.b>x.b:
return 1
elif self.a==x.a and self.b==x.b:
return 0
else:
return -1
v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2
print cmp(v1,v2)
[root@hadron python]# python Vector.py Vector (7, 8) -1 类属性与方法 1)类的私有属性 __private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。 2)类的方法 在类地内部,使用def关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数 3)类的私有方法 __private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 self.__private_methods [root@hadron python]# vi private.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class JustCounter:
__x = 0 # 私有变量
y = 0 # 公开变量
def __f(self):
print "私有方法",self.__x,self.y
def count(self):
self.__x += 1
self.y += 1
print self.__x
self.__f()
c1 = JustCounter()
c1.count()
c2=JustCounter()
c2.count()
print c2.y
[root@hadron python]# python private.py 1 私有方法 1 1 1 私有方法 1 1 1 问题是当我们要调用其中的函数的时候,如何让脚本知道是我们到底是想让它直接运行还是只是作为模块引入另外一个脚本呢? .py有两种使用方式,一种是作为模块被调用,另外一种是直接运行。那么如何判断呢? 在main()函数前加入了一个判断语句,以此来让脚本判断自己是被当做模块调用,还是被直接运行的。 当被import作为模块调用的时候,if以下的代码就不会被执行,也就是说main()函数不会被执行。 #!/usr/bin/env python #A system information gathering script import subprocess #command 1 def uname_func() uname = "uname" uname_arg = "-a" print "gathering system information with $s command:\n" % uname subprocess.call([uname,uname_arg]) #command 2 def disk_func() diskspace = "df" diskspace_arg = "-h" print "gathering diskspace information %s command:\n" % diskspace subprocess.call([diskspace,diskspace_arg]) #main function that call other functions def main() uname_fun() diskspace_fun() if __name__== "__main__": main() 总结一下: 如果我们是直接执行某个.py文件的时候,该文件中那么”__name__ == '__main__'“是True, 但是我们如果从另外一个.py文件通过import导入该文件的时候,这时__name__的值就是我们这个py文件的名字而不是__main__。 这个功能还有一个用处:调试代码的时候,在”if __name__ == '__main__'“中加入一些我们的调试代码,我们可以让外部模块调用的时候不执行我们的调试代码, 但是如果我们想排查问题的时候,直接执行该模块文件,调试代码能够正常运行! 正则表达式 Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。 re 模块使 Python 语言拥有全部的正则表达式功能。 compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。 re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。 re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。 可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。 group() 返回被 RE 匹配的字符串(If a group matches multiple times, only the last match is accessible: ) start() 返回匹配开始的位置 end() 返回匹配结束的位置 span() 返回一个元组包含匹配 (开始,结束) 的位置 (1) [root@hadron python]# vi re1.py #!/usr/bin/python # -*- coding: UTF-8 -*- import re #re.match()返回的是一个对象,不成功返回的是none. #可以通过group(num)或groups()匹配对象函数来获取匹配表达式 m=re.match("in", "in_contain_china") if m: print m print("match:is match") print m.group(),m.span() print '---------' s=re.search("ain","china_contain") if s: print s.group(),s.span() [root@hadron python]# python re1.py <_sre.SRE_Match object at 0x7f5b51d767e8> match:is match in (0, 2) --------- ain (10, 13) 正则表达式修饰符 - 可选标志 re.I 使匹配对大小写不敏感 re.L 做本地化识别(locale-aware)匹配 re.M 多行匹配,影响 ^ 和 $ re.S 使 . 匹配包括换行在内的所有字符 re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 正则表达式模式 ^ 匹配字符串的开头 $ 匹配字符串的末尾。 . 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 [...] 字符集,用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k' [^...] 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 re* 匹配0个或多个的表达式。 re+ 匹配1个或多个的表达式。 re? 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 re{ n} re{ n,} 精确匹配n个前面表达式。 re{ n, m} 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 a| b 匹配a或b (re) 子模式,匹配括号内的表达式,也表示一个组 (?imx) 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 (?-imx) 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 (?: re) 类似 (...), 但是不表示一个组 (?imx: re) 在括号中使用i, m, 或 x 可选标志 (?-imx: re) 在括号中不使用i, m, 或 x 可选标志 (?#...) 注释. (?= re) 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 (?! re) 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功 (?> re) 匹配的独立模式,省去回溯。 \w 匹配字母数字及下划线 \W 匹配非字母数字及下划线 \s 匹配任意空白字符,等价于 [\t\n\r\f]. \S 匹配任意非空字符 \d 匹配任意数字,等价于 [0-9]. \D 匹配任意非数字 \A 匹配字符串开始 \Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。c \z 匹配字符串结束 \G 匹配最后匹配完成的位置。 \b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 \B 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 \n, \t, 等. 匹配一个换行符。匹配一个制表符。等 \1...\9 匹配第n个分组的子表达式。 \10 匹配第n个分组的子表达式,如果它经匹配。否则指的是八进制字符码的表达式。 正则表达式实例 [Pp]ython 匹配 "Python" 或 "python" rub[ye] 匹配 "ruby" 或 "rube" [aeiou] 匹配中括号内的任意一个字母 [0-9] 匹配任何数字。类似于 [0123456789] [a-z] 匹配任何小写字母 [A-Z] 匹配任何大写字母 [a-zA-Z0-9] 匹配任何字母及数字 [^aeiou] 除了aeiou字母以外的所有字符 [^0-9] 匹配除了数字外的字符 . 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。 \d 匹配一个数字字符。等价于 [0-9]。 \D 匹配一个非数字字符。等价于 [^0-9]。 \s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 \S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 \w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。 \W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。 正则表达式使用反斜杠" \ "来代表特殊形式或用作转义字符.为了使正则表达式具有更好的可读性,Python特别设计了原始字符串(raw string). raw string就是用'r'作为字符串的前缀,如 r"\n":表示两个字符"\"和"n",而不是换行符了。Python中写正则表达式时推荐使用这种形式。 (2) [root@hadron python]# vi re2.py #!/usr/bin/python # -*- coding: UTF-8 -*- import re #可选标志 s=re.search('abc','I have ABC',re.I) if s: print s.group() #spit()按照能够匹配的子串将string分割后返回列表 p = re.compile(r'\d+') print p.split('one1two2three3four4') #检索和替换 #Python 的 re 模块提供了re.sub用于替换字符串中的匹配项 phone = "2004-959-559 # 这是一个国外电话号码" # 删除字符串中的 Python注释 num = re.sub(r'#.*$', "", phone) print "电话号码是: ", num # 删除非数字(-)的字符串 num = re.sub(r'\D', "", phone) print "电话号码是 : ", num [root@hadron python]# python re2.py ABC ['one', 'two', 'three', 'four', ''] 电话号码是: 2004-959-559 电话号码是 : 2004959559 (3) [root@hadron python]# vi re3.py #!/usr/bin/python # -*- coding: UTF-8 -*- import re email = raw_input("Please input your Email:\n") #if re.match(r'[0-9a-zA-Z_]{0,19}@163.com',email): if re.match(r'^[0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}\.[com,cn,net]{1,3}$',email) print('Email is Right!') else: print('Please reset your right Email address!') [root@hadron python]# python re3.py Please input your Email: hadron.cheng@qq.com Please reset your right Email address! [root@hadron python]# python re3.py Please input your Email: 6172058@qq.com Email is Right! Python中使用线程有两种方式:函数或者用类来包装线程对象。 函数式:调用thread模块中的start_new_thread()函数来产生新线程 (1) [root@hadron python]# vi mythread.py #!/usr/bin/python # -*- coding: UTF-8 -*- import thread import time # 为线程定义一个函数 def print_time(threadName, delay): count = 0 while count < 5: time.sleep(delay) count += 1 print "%s: %s" % ( threadName, time.ctime(time.time()) ) # 创建两个线程 try: thread.start_new_thread( print_time, ("Thread-1", 2, ) ) thread.start_new_thread( print_time, ("Thread-2", 4, ) ) except: print "Error: unable to start thread" #是个死循环,主要是等待线程执行结束 while 1: pass [root@hadron python]# python mythread.py Thread-1: Tue Jan 24 11:00:18 2017 Thread-2: Tue Jan 24 11:00:20 2017 Thread-1: Tue Jan 24 11:00:20 2017 Thread-1: Tue Jan 24 11:00:22 2017 Thread-2: Tue Jan 24 11:00:24 2017 Thread-1: Tue Jan 24 11:00:24 2017 Thread-1: Tue Jan 24 11:00:26 2017 Thread-2: Tue Jan 24 11:00:28 2017 Thread-2: Tue Jan 24 11:00:32 2017 Thread-2: Tue Jan 24 11:00:36 2017 (2) Python通过两个标准库thread和threading提供对线程的支持。thread提供了低级别的、原始的线程以及一个简单的锁。 使用Threading模块创建线程,直接从threading.Thread继承,然后重写__init__方法和run方法: [root@hadron python]# vi thread2.py #!/usr/bin/python # -*- coding: UTF-8 -*- import threading import time exitFlag = 0 class myThread (threading.Thread): #继承父类threading.Thread def __init__(self, threadID, name, counter): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self): #把要执行的代码写到run函数里面 线程在创建后会直接运行run函数 print "Starting " + self.name print_time(self.name, self.counter, 5) print "Exiting " + self.name def print_time(threadName, delay, counter): while counter: if exitFlag: thread.exit() time.sleep(delay) print "%s: %s" % (threadName, time.ctime(time.time())) counter -= 1 # 创建新线程 thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # 开启线程 thread1.start() thread2.start() print "Exiting Main Thread" [root@hadron python]# python thread2.py Starting Thread-1 Starting Thread-2 Exiting Main Thread Thread-1: Tue Jan 24 11:05:04 2017 Thread-2: Tue Jan 24 11:05:05 2017 Thread-1: Tue Jan 24 11:05:05 2017 Thread-1: Tue Jan 24 11:05:06 2017 Thread-2: Tue Jan 24 11:05:07 2017 Thread-1: Tue Jan 24 11:05:07 2017 Thread-1: Tue Jan 24 11:05:08 2017 Exiting Thread-1 Thread-2: Tue Jan 24 11:05:09 2017 Thread-2: Tue Jan 24 11:05:11 2017 Thread-2: Tue Jan 24 11:05:13 2017 Exiting Thread-2 (3) 线程同步 使用Thread对象的Lock和Rlock可以实现简单的线程同步,这两个对象都有acquire方法和release方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到acquire和release方法之间。 [root@hadron python]# vi thread3.py #!/usr/bin/python # -*- coding: UTF-8 -*- import threading import time class myThread (threading.Thread): def __init__(self, threadID, name, counter): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self): print "Starting " + self.name # 获得锁,成功获得锁定后返回True # 可选的timeout参数不填时将一直阻塞直到获得锁定 # 否则超时后将返回False threadLock.acquire() print_time(self.name, self.counter, 3) # 释放锁 threadLock.release() def print_time(threadName, delay, counter): while counter: time.sleep(delay) print "%s: %s" % (threadName, time.ctime(time.time())) counter -= 1 threadLock = threading.Lock() threads = [] # 创建新线程 thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # 开启新线程 thread1.start() thread2.start() # 添加线程到线程列表 threads.append(thread1) threads.append(thread2) # 等待所有线程完成 for t in threads: t.join() print "Exiting Main Thread" [root@hadron python]# python thread3.py Starting Thread-1 Starting Thread-2 Thread-1: Tue Jan 24 11:09:08 2017 Thread-1: Tue Jan 24 11:09:09 2017 Thread-1: Tue Jan 24 11:09:10 2017 Thread-2: Tue Jan 24 11:09:12 2017 Thread-2: Tue Jan 24 11:09:14 2017 Thread-2: Tue Jan 24 11:09:16 2017 Exiting Main Thread (4) Python的Queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue Queue.qsize() 返回队列的大小 Queue.empty() 如果队列为空,返回True,反之False Queue.full() 如果队列满了,返回True,反之False Queue.full 与 maxsize 大小对应 Queue.get([block[, timeout]])获取队列,timeout等待时间 Queue.get_nowait() 相当Queue.get(False) Queue.put(item) 写入队列,timeout等待时间 Queue.put_nowait(item) 相当Queue.put(item, False) Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号 Queue.join() 实际上意味着等到队列为空,再执行别的操作 [root@hadron python]# vi thread4.py #!/usr/bin/python # -*- coding: UTF-8 -*- import Queue import threading import time exitFlag = 0 class myThread (threading.Thread): def __init__(self, threadID, name, q): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.q = q def run(self): print "Starting " + self.name process_data(self.name, self.q) print "Exiting " + self.name def process_data(threadName, q): while not exitFlag: queueLock.acquire() if not workQueue.empty(): data = q.get() queueLock.release() print "%s processing %s" % (threadName, data) else: queueLock.release() time.sleep(1) threadList = ["Thread-1", "Thread-2", "Thread-3"] nameList = ["One", "Two", "Three", "Four", "Five"] queueLock = threading.Lock() workQueue = Queue.Queue(10) threads = [] threadID = 1 # 创建新线程 for tName in threadList: thread = myThread(threadID, tName, workQueue) thread.start() threads.append(thread) threadID += 1 # 填充队列 queueLock.acquire() for word in nameList: workQueue.put(word) queueLock.release() # 等待队列清空 while not workQueue.empty(): pass # 通知线程是时候退出 exitFlag = 1 # 等待所有线程完成 for t in threads: t.join() print "Exiting Main Thread" [root@hadron python]# python thread4.py Starting Thread-1 Starting Thread-2 Starting Thread-3 Thread-3 processing One Thread-1 processing Two Thread-2 processing Three Thread-3 processing Four Thread-1 processing Five Exiting Thread-2 Exiting Thread-3 Exiting Thread-1 Exiting Main Thread Python JSON [root@hadron 下载]# cp demjson-2.2.4.tar.gz /opt [root@hadron 下载]# cd /opt [root@hadron opt]# tar -zxvf demjson-2.2.4.tar.gz demjson-2.2.4/ demjson-2.2.4/docs/ demjson-2.2.4/docs/HOOKS.txt demjson-2.2.4/docs/demjson.txt demjson-2.2.4/docs/jsonlint.txt demjson-2.2.4/docs/NEWS.txt demjson-2.2.4/docs/PYTHON3.txt demjson-2.2.4/docs/INSTALL.txt demjson-2.2.4/docs/CHANGES.txt demjson-2.2.4/PKG-INFO demjson-2.2.4/README.md demjson-2.2.4/LICENSE.txt demjson-2.2.4/README.txt demjson-2.2.4/setup.py demjson-2.2.4/jsonlint demjson-2.2.4/demjson.py demjson-2.2.4/test/ demjson-2.2.4/test/test_demjson.py [root@hadron opt]# cd demjson-2.2.4/ [root@hadron demjson-2.2.4]# [root@hadron demjson-2.2.4]# python setup.py install running install running build running build_py creating build creating build/lib copying demjson.py -> build/lib running build_scripts creating build/scripts-2.7 copying and adjusting jsonlint -> build/scripts-2.7 changing mode of build/scripts-2.7/jsonlint from 644 to 755 running install_lib copying build/lib/demjson.py -> /usr/lib/python2.7/site-packages byte-compiling /usr/lib/python2.7/site-packages/demjson.py to demjson.pyc running install_scripts copying build/scripts-2.7/jsonlint -> /usr/bin changing mode of /usr/bin/jsonlint to 755 running install_egg_info Writing /usr/lib/python2.7/site-packages/demjson-2.2.4-py2.7.egg-info [root@hadron python]# vi json1.py #!/usr/bin/python import demjson data = [ { 'a' : 1, 'b' : 2, 'c' : 3, 'd' : 4, 'e' : 5 } ] json = demjson.encode(data) print json [root@hadron python]# python json1.py [{"a":1,"b":2,"c":3,"d":4,"e":5}] [root@hadron python]# vi json2.py #!/usr/bin/python import demjson json = '{"a":1,"b":2,"c":3,"d":4,"e":5}'; text = demjson.decode(json) print text [root@hadron python]# python json2.py {u'a': 1, u'c': 3, u'b': 2, u'e': 5, u'd': 4} Python XML解析 常见的XML编程接口有DOM和SAX (1) python使用SAX解析xml python 标准库包含SAX解析器,SAX用事件驱动模型,通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件 在python中使用sax方式处理xml要先引入xml.sax中的parse函数,还有xml.sax.handler中的ContentHandler ContentHandler类方法介绍 characters(content)方法 调用时机: 从行开始,遇到标签之前,存在字符,content的值为这些字符串。 从一个标签,遇到下一个标签之前, 存在字符,content的值为这些字符串。 从一个标签,遇到行结束符之前,存在字符,content的值为这些字符串。 标签可以是开始标签,也可以是结束标签。 startDocument():文档启动的时候调用。 endDocument():解析器到达文档结尾时调用。 startElement(name, attrs):遇到XML开始标签时调用,name是标签的名字,attrs是标签的属性值字典。 endElement(name):遇到XML结束标签时调用。 [root@hadron python]# vi mySAX.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import xml.sax
class MovieHandler( xml.sax.ContentHandler ):
def __init__(self):
self.CurrentData = ""
self.type = ""
self.format = ""
self.year = ""
self.rating = ""
self.stars = ""
self.description = ""
# 元素开始事件处理
def startElement(self, tag, attributes):
self.CurrentData = tag
if tag == "movie":
print "*****Movie*****"
title = attributes["title"]
print "Title:", title
# 元素结束事件处理
def endElement(self, tag):
if self.CurrentData == "type":
print "Type:", self.type
elif self.CurrentData == "format":
print "Format:", self.format
elif self.CurrentData == "year":
print "Year:", self.year
elif self.CurrentData == "rating":
print "Rating:", self.rating
elif self.CurrentData == "stars":
print "Stars:", self.stars
elif self.CurrentData == "description":
print "Description:", self.description
self.CurrentData = ""
# 内容事件处理
def characters(self, content):
if self.CurrentData == "type":
self.type = content
elif self.CurrentData == "format":
self.format = content
elif self.CurrentData == "year":
self.year = content
elif self.CurrentData == "rating":
self.rating = content
elif self.CurrentData == "stars":
self.stars = content
elif self.CurrentData == "description":
self.description = content
if ( __name__ == "__main__"):
# 创建一个 XMLReader
parser = xml.sax.make_parser()
# turn off namepsaces
parser.setFeature(xml.sax.handler.feature_namespaces, 0)
# 重写 ContextHandler
Handler = MovieHandler()
parser.setContentHandler( Handler )
parser.parse("movies.xml")
[root@hadron python]# python mySAX.py *****Movie***** Title: Enemy Behind Type: War, Thriller Format: DVD Year: 2003 Rating: PG Stars: 10 Description: Talk about a US-Japan war *****Movie***** Title: Transformers Type: Anime, Science Fiction Format: DVD Year: 1989 Rating: R Stars: 8 Description: A schientific fiction *****Movie***** Title: Trigun Type: Anime, Action Format: DVD Rating: PG Stars: 10 Description: Vash the Stampede! *****Movie***** Title: Ishtar Type: Comedy Format: VHS Rating: PG Stars: 2 Description: Viewable boredom (2) 使用xml.dom解析xml 一个 DOM 的解析器在解析一个 XML 文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里, 之后你可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件。 python中用xml.dom.minidom来解析xml文件 [root@hadron python]# vi dom.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from xml.dom.minidom import parse
import xml.dom.minidom
# 使用minidom解析器打开 XML 文档
DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
print "Root element : %s" % collection.getAttribute("shelf")
# 在集合中获取所有电影
movies = collection.getElementsByTagName("movie")
# 打印每部电影的详细信息
for movie in movies:
print "*****Movie*****"
if movie.hasAttribute("title"):
print "Title: %s" % movie.getAttribute("title")
type = movie.getElementsByTagName('type')[0]
print "Type: %s" % type.childNodes[0].data
format = movie.getElementsByTagName('format')[0]
print "Format: %s" % format.childNodes[0].data
rating = movie.getElementsByTagName('rating')[0]
print "Rating: %s" % rating.childNodes[0].data
description = movie.getElementsByTagName('description')[0]
print "Description: %s" % description.childNodes[0].data
[root@hadron python]# python dom.py Root element : New Arrivals *****Movie***** Title: Enemy Behind Type: War, Thriller Format: DVD Rating: PG Description: Talk about a US-Japan war *****Movie***** Title: Transformers Type: Anime, Science Fiction Format: DVD Rating: R Description: A schientific fiction *****Movie***** Title: Trigun Type: Anime, Action Format: DVD Rating: PG Description: Vash the Stampede! *****Movie***** Title: Ishtar Type: Comedy Format: VHS Rating: PG Description: Viewable boredom python操作mysql数据库 MySQLdb 是用于Python链接Mysql数据库的接口,它实现了 Python 数据库 API 规范 V2.0 (1) [root@hadron python]# vi mysql.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import MySQLdb
[root@hadron python]# python mysql.py Traceback (most recent call last): File "mysql.py", line 4, in <module> import MySQLdb ImportError: No module named MySQLdb 意味着你没有安装 MySQLdb 模块 (2) [root@hadron 下载]# tar -zxvf MySQL-python-1.2.4b4.tar.gz -C /opt [root@hadron MySQL-python-1.2.4b4]# python setup.py build Downloading http://pypi.python.org/packages/source/d/distribute/distribute-0.6.28.tar.gz Extracting in /tmp/tmpz4y_0u Now working in /tmp/tmpz4y_0u/distribute-0.6.28 Building a Distribute egg in /opt/MySQL-python-1.2.4b4 /opt/MySQL-python-1.2.4b4/distribute-0.6.28-py2.7.egg sh: mysql_config: 未找到命令 Traceback (most recent call last): File "setup.py", line 18, in <module> metadata, options = get_config() File "/opt/MySQL-python-1.2.4b4/setup_posix.py", line 43, in get_config libs = mysql_config("libs_r") File "/opt/MySQL-python-1.2.4b4/setup_posix.py", line 25, in mysql_config raise EnvironmentError("%s not found" % (mysql_config.path,)) EnvironmentError: mysql_config not found [root@hadron MySQL-python-1.2.4b4]# yum install python-devel [root@hadron MySQL-python-1.2.4b4]# yum install mariadb-devel [root@hadron MySQL-python-1.2.4b4]# python setup.py build running build running build_py creating build creating build/lib.linux-x86_64-2.7 copying _mysql_exceptions.py -> build/lib.linux-x86_64-2.7 creating build/lib.linux-x86_64-2.7/MySQLdb copying MySQLdb/__init__.py -> build/lib.linux-x86_64-2.7/MySQLdb copying MySQLdb/converters.py -> build/lib.linux-x86_64-2.7/MySQLdb copying MySQLdb/connections.py -> build/lib.linux-x86_64-2.7/MySQLdb copying MySQLdb/cursors.py -> build/lib.linux-x86_64-2.7/MySQLdb copying MySQLdb/release.py -> build/lib.linux-x86_64-2.7/MySQLdb copying MySQLdb/times.py -> build/lib.linux-x86_64-2.7/MySQLdb creating build/lib.linux-x86_64-2.7/MySQLdb/constants copying MySQLdb/constants/__init__.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants copying MySQLdb/constants/CR.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants copying MySQLdb/constants/FIELD_TYPE.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants copying MySQLdb/constants/ER.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants copying MySQLdb/constants/FLAG.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants copying MySQLdb/constants/REFRESH.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants copying MySQLdb/constants/CLIENT.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants running build_ext building '_mysql' extension creating build/temp.linux-x86_64-2.7 gcc -pthread -fno-strict-aliasing -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -Dversion_info=(1,2,4,'beta',4) -D__version__=1.2.4b4 -I/usr/include/mysql -I/usr/include/python2.7 -c _mysql.c -o build/temp.linux-x86_64-2.7/_mysql.o gcc -pthread -shared -Wl,-z,relro build/temp.linux-x86_64-2.7/_mysql.o -L/usr/lib64/mysql -L/usr/lib64 -lmysqlclient -lpthread -lz -lm -lssl -lcrypto -ldl -lpython2.7 -o build/lib.linux-x86_64-2.7/_mysql.so [root@hadron MySQL-python-1.2.4b4]# python setup.py install running install running bdist_egg running egg_info writing MySQL_python.egg-info/PKG-INFO writing top-level names to MySQL_python.egg-info/top_level.txt writing dependency_links to MySQL_python.egg-info/dependency_links.txt writing MySQL_python.egg-info/PKG-INFO writing top-level names to MySQL_python.egg-info/top_level.txt writing dependency_links to MySQL_python.egg-info/dependency_links.txt reading manifest file 'MySQL_python.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' writing manifest file 'MySQL_python.egg-info/SOURCES.txt' installing library code to build/bdist.linux-x86_64/egg running install_lib running build_py copying MySQLdb/release.py -> build/lib.linux-x86_64-2.7/MySQLdb running build_ext creating build/bdist.linux-x86_64 creating build/bdist.linux-x86_64/egg creating build/bdist.linux-x86_64/egg/MySQLdb copying build/lib.linux-x86_64-2.7/MySQLdb/__init__.py -> build/bdist.linux-x86_64/egg/MySQLdb copying build/lib.linux-x86_64-2.7/MySQLdb/converters.py -> build/bdist.linux-x86_64/egg/MySQLdb copying build/lib.linux-x86_64-2.7/MySQLdb/release.py -> build/bdist.linux-x86_64/egg/MySQLdb copying build/lib.linux-x86_64-2.7/MySQLdb/times.py -> build/bdist.linux-x86_64/egg/MySQLdb creating build/bdist.linux-x86_64/egg/MySQLdb/constants copying build/lib.linux-x86_64-2.7/MySQLdb/constants/__init__.py -> build/bdist.linux-x86_64/egg/MySQLdb/constants copying build/lib.linux-x86_64-2.7/MySQLdb/constants/ER.py -> build/bdist.linux-x86_64/egg/MySQLdb/constants copying build/lib.linux-x86_64-2.7/MySQLdb/constants/FLAG.py -> build/bdist.linux-x86_64/egg/MySQLdb/constants copying build/lib.linux-x86_64-2.7/MySQLdb/constants/REFRESH.py -> build/bdist.linux-x86_64/egg/MySQLdb/constants copying build/lib.linux-x86_64-2.7/MySQLdb/constants/CR.py -> build/bdist.linux-x86_64/egg/MySQLdb/constants copying build/lib.linux-x86_64-2.7/MySQLdb/constants/FIELD_TYPE.py -> build/bdist.linux-x86_64/egg/MySQLdb/constants copying build/lib.linux-x86_64-2.7/MySQLdb/constants/CLIENT.py -> build/bdist.linux-x86_64/egg/MySQLdb/constants copying build/lib.linux-x86_64-2.7/MySQLdb/connections.py -> build/bdist.linux-x86_64/egg/MySQLdb copying build/lib.linux-x86_64-2.7/MySQLdb/cursors.py -> build/bdist.linux-x86_64/egg/MySQLdb copying build/lib.linux-x86_64-2.7/_mysql_exceptions.py -> build/bdist.linux-x86_64/egg copying build/lib.linux-x86_64-2.7/_mysql.so -> build/bdist.linux-x86_64/egg byte-compiling build/bdist.linux-x86_64/egg/MySQLdb/__init__.py to __init__.pyc byte-compiling build/bdist.linux-x86_64/egg/MySQLdb/converters.py to converters.pyc byte-compiling build/bdist.linux-x86_64/egg/MySQLdb/release.py to release.pyc byte-compiling build/bdist.linux-x86_64/egg/MySQLdb/times.py to times.pyc byte-compiling build/bdist.linux-x86_64/egg/MySQLdb/constants/__init__.py to __init__.pyc byte-compiling build/bdist.linux-x86_64/egg/MySQLdb/constants/ER.py to ER.pyc byte-compiling build/bdist.linux-x86_64/egg/MySQLdb/constants/FLAG.py to FLAG.pyc byte-compiling build/bdist.linux-x86_64/egg/MySQLdb/constants/REFRESH.py to REFRESH.pyc byte-compiling build/bdist.linux-x86_64/egg/MySQLdb/constants/CR.py to CR.pyc byte-compiling build/bdist.linux-x86_64/egg/MySQLdb/constants/FIELD_TYPE.py to FIELD_TYPE.pyc byte-compiling build/bdist.linux-x86_64/egg/MySQLdb/constants/CLIENT.py to CLIENT.pyc byte-compiling build/bdist.linux-x86_64/egg/MySQLdb/connections.py to connections.pyc byte-compiling build/bdist.linux-x86_64/egg/MySQLdb/cursors.py to cursors.pyc byte-compiling build/bdist.linux-x86_64/egg/_mysql_exceptions.py to _mysql_exceptions.pyc creating stub loader for _mysql.so byte-compiling build/bdist.linux-x86_64/egg/_mysql.py to _mysql.pyc creating build/bdist.linux-x86_64/egg/EGG-INFO copying MySQL_python.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO copying MySQL_python.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO copying MySQL_python.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO copying MySQL_python.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO writing build/bdist.linux-x86_64/egg/EGG-INFO/native_libs.txt zip_safe flag not set; analyzing archive contents... creating dist creating 'dist/MySQL_python-1.2.4b4-py2.7-linux-x86_64.egg' and adding 'build/bdist.linux-x86_64/egg' to it removing 'build/bdist.linux-x86_64/egg' (and everything under it) Processing distribute-0.6.28-py2.7.egg creating /usr/lib64/python2.7/site-packages/distribute-0.6.28-py2.7.egg Extracting distribute-0.6.28-py2.7.egg to /usr/lib64/python2.7/site-packages Adding distribute 0.6.28 to easy-install.pth file Installing easy_install script to /usr/bin Installing easy_install-2.7 script to /usr/bin Installed /usr/lib64/python2.7/site-packages/distribute-0.6.28-py2.7.egg Processing dependencies for distribute==0.6.28 Finished processing dependencies for distribute==0.6.28 Processing MySQL_python-1.2.4b4-py2.7-linux-x86_64.egg creating /usr/lib64/python2.7/site-packages/MySQL_python-1.2.4b4-py2.7-linux-x86_64.egg Extracting MySQL_python-1.2.4b4-py2.7-linux-x86_64.egg to /usr/lib64/python2.7/site-packages Adding MySQL-python 1.2.4b4 to easy-install.pth file Installed /usr/lib64/python2.7/site-packages/MySQL_python-1.2.4b4-py2.7-linux-x86_64.egg Processing dependencies for MySQL-python==1.2.4b4 Finished processing dependencies for MySQL-python==1.2.4b4 (3) [root@hadron python]# vi mysql.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import MySQLdb
# 打开数据库连接
db = MySQLdb.connect("localhost","root","123456","test")
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# 使用execute方法执行SQL语句
cursor.execute("SELECT VERSION()")
# 使用 fetchone() 方法获取一条数据库
data = cursor.fetchone()
print "Database version : %s " % data
db.close()
[root@hadron python]# python mysql.py Database version : 5.5.52-MariaDB (4) [root@hadron python]# vi mysql2.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import MySQLdb
# 打开数据库连接
db = MySQLdb.connect("localhost","root","123456","test")
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# 如果数据表已经存在使用 execute() 方法删除表。
cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")
# 创建数据表SQL语句
sql = """CREATE TABLE EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
SEX CHAR(1),
INCOME FLOAT )"""
cursor.execute(sql)
print "创建表成功!"
# SQL 插入语句
sql = "INSERT INTO EMPLOYEE(FIRST_NAME, \
LAST_NAME, AGE, SEX, INCOME) \
VALUES ('%s', '%s', '%d', '%c', '%d' )" % \
('Mac', 'Mohan', 20, 'M', 2000)
try:
# 执行sql语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
print "插入1条记录"
except:
# Rollback in case there is any error
db.rollback()
# SQL 查询语句
sql = "SELECT * FROM EMPLOYEE \
WHERE INCOME > '%d'" % (1000)
try:
# 执行SQL语句
cursor.execute(sql)
# 获取所有记录列表
results = cursor.fetchall()
for row in results:
fname = row[0]
lname = row[1]
age = row[2]
sex = row[3]
income = row[4]
# 打印结果
print "fname=%s,lname=%s,age=%d,sex=%s,income=%d" % \
(fname, lname, age, sex, income )
except:
print "Error: unable to fecth data"
# 关闭数据库连接
db.close()
[root@hadron python]# python mysql2.py mysql2.py:10: Warning: Unknown table 'EMPLOYEE' cursor.execute("DROP TABLE IF EXISTS EMPLOYEE") 创建表成功! 插入1条记录 fname=Mac,lname=Mohan,age=20,sex=M,income=2000 MariaDB [test]> show tables; +----------------+ | Tables_in_test | +----------------+ | EMPLOYEE | +----------------+ 1 row in set (0.00 sec) MariaDB [test]> select * from EMPLOYEE; +------------+-----------+------+------+--------+ | FIRST_NAME | LAST_NAME | AGE | SEX | INCOME | +------------+-----------+------+------+--------+ | Mac | Mohan | 20 | M | 2000 | +------------+-----------+------+------+--------+ 1 row in set (0.00 sec) Python调用Linux命令 Python目前已经废弃了os.system,os.spawn*,os.popen*,popen2.*,commands.*来执行其他语言的命令,subprocesss是被推荐的方法; subprocess允许你能创建很多子进程,创建的时候能指定子进程和子进程的输入、输出、错误输出管道,执行后能获取输出结果和执行状态。 subprocess模块在python2.4中初次亮相,其中集中了关于进程的诸多操作,其中的call()完全替代了system(),而popen()被更为丰富的Popen类替代; (1) [root@hadron python]# vi cmd.py
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#python wapper for the ls command
import subprocess
subprocess.call(["ls","-l"])
subprocess.call(["cat","/root/python/cmd.py"])
#系统信息
uname = "uname"
uname_arg = "-a"
print "Gathering system information with %s command:\n" % uname
subprocess.call([uname,uname_arg])
[root@hadron python]# python cmd.py 总用量 196 -rw-r--r-- 1 root root 320 1月 24 15:30 cmd.py -rwxr-xr-x 1 root root 245 1月 22 13:39 dict.py ..................... -rw-r--r-- 1 root root 261 1月 23 14:00 try2.py -rw-r--r-- 1 root root 272 1月 23 13:46 try.py -rwxr-xr-x 1 root root 234 1月 23 09:04 var.py -rw-r--r-- 1 root root 510 1月 23 15:22 Vector.py #!/usr/bin/env python # -*- coding: UTF-8 -*- #python wapper for the ls command import subprocess subprocess.call(["ls","-l"]) subprocess.call(["cat","/root/python/cmd.py"]) #系统信息 uname = "uname" uname_arg = "-a" print "Gathering system information with %s command:\n" % uname subprocess.call([uname,uname_arg]) Gathering system information with uname command:
Linux hadron 3.10.0-514.2.2.el7.x86_64 #1 SMP Tue Dec 6 23:06:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
(2) [root@hadron python]# vi LocalUtil.py #!/usr/bin/env python # -*- coding: UTF-8 -*- import shlex import datetime import subprocess import time def execute_command(cmdstring, cwd=None, timeout=None, shell=False): """执行一个SHELL命令 封装了subprocess的Popen方法, 支持超时判断,支持读取stdout和stderr 参数: cwd: 运行命令时更改路径,如果被设定,子进程会直接先更改当前路径到cwd timeout: 超时时间,秒,支持小数,精度0.1秒 shell: 是否通过shell运行 Returns: return_code Raises: Exception: 执行超时 """ if shell: cmdstring_list = cmdstring else: cmdstring_list = shlex.split(cmdstring) if timeout: end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout) #没有指定标准输出和错误输出的管道,因此会打印到屏幕上; sub = subprocess.Popen(cmdstring_list, cwd=cwd, stdin=subprocess.PIPE,shell=shell,bufsize=4096) #subprocess.poll()方法:检查子进程是否结束了,如果结束了,设定并返回码,放在subprocess.returncode变量中 while sub.poll() is None: time.sleep(0.1) if timeout: if end_time <= datetime.datetime.now(): raise Exception("Timeout:%s"%cmdstring) return str(sub.returncode) if __name__=="__main__": print execute_command("ls") [root@hadron python]# python LocalUtil.py cmd.py elif.py file2.py fun.py import.py lambda.py mySAX.py mythread.py Parent.py re1.py str.py dict.py Employee.py file3.py fun.pyc in_is.py LocalUtil.py myServer.py mytime.py Point.py re2.py dir.py Emp.py for.py hello.py json1.py movies.xml mysql2.py mytuple.py print.py re3.py t dom.py file1.py from_import.py if.py json2.py mylist.py mysql.py override.py private.py server.py 0 [root@hadron python]# vi cmd2.py #!/usr/bin/env python # -*- coding: UTF-8 -*- import LocalUtil LocalUtil.execute_command('uname -a') [root@hadron python]# python cmd2.py Linux hadron 3.10.0-514.2.2.el7.x86_64 #1 SMP Tue Dec 6 23:06:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux Python Paramiko模块安装和使用 大家会发现,常见的解决方法都会需要对远程服务器必要的配置,如果远程服务器只有一两台还好说,如果有N台,还需要逐台进行配置,或者需要使用代码进行以上操作时,上面的办法就不太方便了。使用paramiko可以很好的解决以上问题,比起前面的方法,它仅需要在本地上安装相应的软件(python以及PyCrypto),对远程服务器没有配置要求,对于连接多台服务器,进行复杂的连接操作特别有帮助。 安装paramiko有两个先决条件,python和另外一个名为PyCrypto的模块。 [root@hadron 下载]# wget http://ftp.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-2.6.tar.gz [root@hadron 下载]# tar -zxvf pycrypto-2.6.tar.gz -C /opt [root@hadron 下载]# cd /opt/pycrypto-2.6/ [root@hadron pycrypto-2.6]# python setup.py build && python setup.py install [root@hadron pycrypto-2.6]# python Python 2.7.5 (default, Nov 6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import Crypto >>> 下载:https://pypi.python.org/pypi/paramiko/2.1.1 [root@hadron 下载]# tar -zxvf paramiko-2.1.1.tar.gz -C /opt [root@hadron 下载]# cd /opt/paramiko-2.1.1/ [root@hadron paramiko-2.1.1]# python setup.py build && python setup.py install [root@hadron paramiko-2.1.1]# python Python 2.7.5 (default, Nov 6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import paramiko >>> 使用用户名密码连接远程主机 [root@hadron python]# vi paramikoDemo.py #!/usr/bin/env python # -*- coding: UTF-8 -*- import paramiko import sys,os hostname='192.168.1.169' username='root' password='123456' #通过sys下的argv来获取命令行的输入 cmd=sys.argv[1] if __name__=='__main__': paramiko.util.log_to_file('paramiko.log') s=paramiko.SSHClient() #加载本地的known_hosts文件 s.load_system_host_keys() #用于允许连接不在known_hosts名单中的主机 s.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #连接远程主机 s.connect(hostname=hostname,username=username,password=password) #执行命令 stdin,stdout,stderr=s.exec_command(cmd) #读取命令结果 print stdout.read() print stderr.read() s.close() [root@hadron python]# python paramikoDemo.py free total used free shared buff/cache available Mem: 7995716 583520 5689056 16816 1723140 7145116 Swap: 4194300 0 4194300 [root@hadron python]# python paramikoDemo.py 'df -h' Filesystem Size Used Avail Use% Mounted on /dev/mapper/centos-root 36G 2.3G 34G 7% / devtmpfs 3.9G 0 3.9G 0% /dev tmpfs 3.9G 0 3.9G 0% /dev/shm tmpfs 3.9G 17M 3.8G 1% /run tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup /dev/sda1 497M 125M 373M 26% /boot tmpfs 781M 0 781M 0% /run/user/0 [root@hadron python]# vi remote.py #!/usr/bin/env python # -*- coding: UTF-8 -*- import paramiko def python_ssh(hostname,username,password,**shell): try: s = paramiko.SSHClient() s.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 用于允许连接不在known_hosts名单中的主机 s.connect(hostname = hostname,username = username,password = password) result = {} for key in shell: stdin,stdout,stderr = s.exec_command(shell[key]) result[key] = stdout.read(),stderr.read() s.close() return result except: result = u"无" return result [root@hadron python]# vi sshDemo.py #!/usr/bin/env python # -*- coding: UTF-8 -*- from remote import python_ssh result=python_ssh('192.168.1.169','root','123456',SHELL1='free') print result [root@hadron python]# python sshDemo.py {'SHELL1': (' total used free shared buff/cache available\n Mem: 7995716 583492 5689252 16820 1722972 7145300\n Swap: 4194300 0 4194300\n', '')} 使用key连接远程主机 将本地公钥发送给远程主机认证方 [root@hadron .ssh]# cat id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC....eGTXv5dt4ZcyLnA4BIS/x root@node1 [root@node3 .ssh]# vi authorized_keys [root@hadron python]# vi privatekey.py #!/usr/bin/env python # -*- coding: UTF-8 -*- import paramiko import sys,os host = sys.argv[1] user = 'root' #指定用来解密的私钥的路径 pkey_file = '/root/.ssh/id_rsa' #使用私钥解密 key = paramiko.RSAKey.from_private_key_file(pkey_file) cmd = sys.argv[2] s = paramiko.SSHClient() s.load_system_host_keys() s.set_missing_host_key_policy(paramiko.AutoAddPolicy()) s.connect(host,22,user,pkey=key,timeout=5) stdin,stdout,stderr=s.exec_command(cmd) cmd_result = stdout.read(),stderr.read() for line in cmd_result: print line, s.close() [root@hadron python]# python privatekey.py 192.168.1.120 df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda1 153525000 141787340 11737660 93% / devtmpfs 65946880 0 65946880 0% /dev tmpfs 65961464 280 65961184 1% /dev/shm tmpfs 65961464 59300 65902164 1% /run tmpfs 65961464 0 65961464 0% /sys/fs/cgroup /dev/sda3 283712156 32928 283679228 1% /data tmpfs 13192296 16 13192280 1% /run/user/988 tmpfs 13192296 32 13192264 1% /run/user/0 /dev/sdb1 1952559608 34260612 1918298996 2% /sdb Paramiko SFTP传送文件 [root@hadron python]# vi sftp.py #!/usr/bin/env python # -*- coding: UTF-8 -*- import paramiko import sys,os host = sys.argv[1] user = 'root' password='123456' t = paramiko.Transport((host,22)) #连接方式也可以用key,这里只需要将password=password改为pkey=key,其余的key代码与前面的一样 t.connect(username=user,password=password) sftp = paramiko.SFTPClient.from_transport(t) #使用t的设置方式连接远程主机 sftp.get('/tmp/hello.txt','hello.txt') #下载文件 sftp.put('hello.py','/tmp/hello.py') #上传文件 t.close(); [root@hadron python]# python sftp.py 192.168.1.169 [root@hadron python]# cat hello.txt Hello,World! [root@webServer tmp]# ls hello.py hello.txt hsperfdata_root