循环语句
while 循环
while 循环语法结构
当需要语句不断的重复执行时,可以使用 while 循环
while expression:
while_sutie
语句 while_suite 会被连续不断的循环执行,直到表达式的值变成 0 或 False
#!/usr/bin/env python
# -- coding: utf-8 --
sum100 = 0
counter = 1
while counter <=100:
sum100 +=counter
counter +=1
print "result is: %d " % sum100
break 语句
break 语句可以结束当前循环然后跳转到下条语句
写程序时,应尽量避免重复的代码,在这种情况下可以使用 while-break 结构
name = raw_input('username: ')
while name != 'tom':
name = raw_input("username: ")
可以替换为
while Ture:
name = raw_input("username: ")
if name == 'tom'
break
#!/usr/bin/env python
# --coding: utf-8 --
while True:
yn = raw_input("Continue(Y/N)? ")
# break 作用:当 yn 在 yY 中则跳出 while 循环,即不再执行 print
if yn in 'yY':
break
print 'working....'
continue 语句
当遇到continue语句时,程序会终止当前循环,并忽略剩余的语句,然后回到循环的顶端
如果仍然满足循环条件,循环提内语句继续执行,否则退出循环
#!/usr/bin/env python
# --coding: utf-8 --
sum100 = 0
counter = 1
while counter <= 100:
counter += 1
if counter % 2:
continue
sum100 += counter
print "result is: %d " % sum100
else 语句
python 中的 while 语句也支持else子句
else子句只在循环完成后执行
break语句也会跳过else块
#!/usr/bin/env python
# --coding: utf-8 --
sum10 = 0
i = 1
while i <=10:
sum10 +=1
else:
print sum10
插曲:
>>> import webbrowser
>>> help(webbrowser)
>>> webbrowser.open_new_tab("http://www.baidu.com") #可以打开一个新的网页
True
>>> webbrowser.open_new_tab("http://192.168.2.100") # 同上。
True
>>> import os
>>> os.system('ls /home/qihang/')
刷博客的循环(初级模式)
#!/usr/bin/env python
# --coding: utf-8 --
import webbrowser
import time
import os
url = "http://192.168.1.107"
counter = 0
while counter < 11:
webbrowser.open_new_tab(url)
time.sleep(0.5) #睡0.5秒
counter +=1
if not counter % 10:
os.system('killall firefox')
for 循环
for 循环语法结构
python中的for接受可迭代对象(例如序列或迭代器)作为其参数,每次迭代其中一个元素
for iten_var in iterable:
suite_expression
>>> for ch in 'abcd':
... print ch
...
a
b
c
d
>>> for ch in ["hello","wold"]:
... print ch
...
hello
wold
与while循环一样,支持break/continue/else 语句
一般情况下,循环次数未知采用 while 循环,循环次数已知,采用 for 循环
range 函数
for循环常与range函数一起使用
range函数提供循环条件
range函数的完整语法为:
range(start,end,step=1)
>>> range(5)
[0, 1, 2, 3, 4]
>>> range(1,5)
[1, 2, 3, 4]
>>> range(1,5,2)
[1, 3]
>>> range(10,0,-1)
>>> for i in range(3):
... print "hello world!"
...
hello world!
hello world!
hello world!
>>> alist = ['bob','alict','tom','jerry']
>>> for i in range(len(alist)):
... print "%s: %s" %(i,alist[i])
...
0: bob
1: alict
2: tom
3: jerry
xrange 函数
xrange()类似range(),不过当你有一个很大的范围列表时,xrange()可以更为适合,因为它不会在内存里创建列表的完整拷贝。
它只被用在for循环中,在for循环外使用它没有意义
它的性能远高出range(),因为它不生成整个列表
>>> for x in xrange(3):
... print x
...
0
1
2
注意:print x 后面 加“,”,可以不用换行。
斐波那契数列
1、斐波那契数列就是某一个数,总是前两个数之和,比如0,1,1,2,3,5,8
2、使用for循环和range()函数编写一个程序,加算有10个数的斐波那契数列
3、改进程序,要求用户输入一个数字,可以生成用户需要长度的斐波那契数列
#!/usr/bin/env python
# --coding: utf-8 --
num = int(raw_input("number")
fib = [0,1]
for i in range(num - 2):
fib.append(fib[-1] + fib[-2])
print fib
一个小练习,使用python来ping 一个网段的主机存活
#!/usr/bin/env python
import os
for i in range(1,255):
ip = "192.168.1.%s" % i
result = os.system("ping -c2 %s > /dev/null" % ip)
if result:
print "%s: down" %ip
else:
print "%s:up" %ip
列表解析
它是一个非常有用、简单、而且灵活的工具,可以用来动态地创建列表
语法:
[expr for iter_var in iterable]
>>> ['hello' for i in range(2)]
['hello', 'hello']
>>> [i for i in range(1,10)]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [i ** 2 for i in range(1,10)]
[1, 4, 9, 16, 25, 36, 49, 64, 81]
这个语句的核心是for循环,它迭代iterable对象的所有条目
expr 应用与序列的每个成员,最后的结果是该表达式产生的列表
文件对象
文件打开方法
open及file 内建函数
作为打开文件之门的“钥匙”,内建函数open()以及file()提供了初始化输入/输出(I/O)操作的通用接口
成功打开文件后会返回一个文件对象,否则引发一个错误
open()方法和file()方法可以完全相互替换
基本语法:
file_object = open(file_name,access_mode='r',buffering=-1)
>>> f = open('/etc/hosts')
>>> f
<open file '/etc/hosts', mode 'r' at 0xb744e0d0>
>>> f.read()
'127.0.0.1\tlocalhost\n127.0.1.1\tqihang-Lenovo-G460\n\n# The following lines are desirable for IPv6 capable hosts\n::1 ip6-localhost ip6-loopback\nfe00::0 ip6-localnet\nff00::0 ip6-mcastprefix\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n'
>>> f.close()
>>> f = open('/etc/hosts')
>>> data = f.read()
>>> print data,
127.0.0.1 localhost
127.0.1.1 qihang-Lenovo-G460
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
>>> f.close()
文件对象的访问模式:
文件模式 | 操作 |
r | 以读方式打开(文件不存在则报错)) |
w | 以写方式打开(文件存在则清空,不存在则创建) |
a | 以追加模式打开(必要时创建新文件) |
r+ | 以读写模式打开(参见r) |
w+ | 以读写模式打开(参见w) |
a+ | 以读写模式打开(参见a) |
文件输入
read方法
read()方法用来直接读取字节到字符串中,最多读取给定数目个字节
如果没有给定size参数(默认值为-1)或者size值为负,文件将被读取直至末尾
>>> data = fobj.read()
>>> print data
readline 方法
>>> f = open('/etc/hosts')
>>> f.readline()
'127.0.0.1\tlocalhost\n'
>>> f.readline()
'127.0.1.1\tqihang-Lenovo-G460\n'
>>> f.close()
readlines 方法
>>> f = open('/etc/hosts')
>>> f.readlines()
['127.0.0.1\tlocalhost\n', '127.0.1.1\tqihang-Lenovo-G460\n', '\n', '# The following lines are desirable for IPv6 capable hosts\n', '::1 ip6-localhost ip6-loopback\n', 'fe00::0 ip6-localnet\n', 'ff00::0 ip6-mcastprefix\n', 'ff02::1 ip6-allnodes\n', 'ff02::2 ip6-allrouters\n']
>>> f.close()
文件迭代
如果需要逐行处理文件,可以结合 for 循环迭代文件
迭代文件的方法与处理其他序列类型的数据类似
>>> fobj = open("star.py")
>>> for eachLine in fobj:
... print eachLine,
>>> f = open("/etc/hosts")
>>> for line in f:
... print line,
...
127.0.0.1 localhost
127.0.1.1 qihang-Lenovo-G460
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
>>> f.close()
文件输出
write 方法
write()内建方法功能与read()和readline()相反。它把含有文本数据或二进制数据块的字符串写入到文件中去
写入文件时,不会自动添加行结束标志,需要程序员首手工输入
>>> fobj.write("Hello World!\n")
>>> f = open('hi.txt','w')
>>> f.read()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: File not open for reading
>>> f.write(30)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: expected a character buffer object
>>> f.write('hello world!') # f.write('hello world!\n') 加上\n 换行
>>> f.flush()
>>> exit()
>>> f =open('hi.txt','a')
>>> f.write('new line.\n')
>>> f.close()
>>> exit()
writelines 方法()列表方式)
>>> f.writelines(['2rd lines\n','3rd lines\n'])
>>> f.flush()
>>> f.close()
练习:模拟cp操作
1、创建~/bin/cp.py文件
2、将/bin/ls "拷贝"到/root目录下
3、要求读取/bin/ls 后,每次读取4096字节,依次写入到新文件
4、不要修改原始文件
#!/usr/bin/env python
# coding: utf-8 --
sfname = '/bin/ls'
dfname = '/root/ls'
src_fobj = open(sfname)
dst_fobj = open(dfname,'w')
while True:
data = src_fobj.read(4096)
if not data:
break
dst_fobj.write(data)
src_fobj.close()
dst_fobj.close()
比对md5值,检查文件是否完全相同,检查结果为相同。
小插曲:read文件的时候会直接占用内存个
$ free -m
total used free shared buffers cached
Mem: 1941 1713 227 30 56 283
-/+ buffers/cache: 1372 568
Swap: 1972 513 1459
# dd if=/dev/zero of=ttt.img bs=1M count=100
>>> f = open('ttt.img')
>>> data = f.read()
$ free -m
total used free shared buffers cached
Mem: 1941 1812 128 30 56 281
-/+ buffers/cache: 1474 466
Swap: 1972 513 1459
>>> f.close()
>>> del data
$ free -m
total used free shared buffers cached
Mem: 1941 1722 218 30 56 281
-/+ buffers/cache: 1384 556
Swap: 1972 513 1459
函数
函数基本操作
函数基本概念
函数是对程序逻辑进行结构化或过程化的一种编程方法
将整块代码巧妙地隔离成易于管理的小块
把重复代码放到函数中而不是进行大量的拷贝,这样既能节省空间,也有助于保持一致性
通常函数都是用于实现某一种功能
创建函数
函数是用def语句来创建的,语法如下:
def function_name(arguments):
"function_documentation_string"
function_body_stuite
#!/usr/bin/env python
# --coding: utf-8 --
#define function
def pstar():
print '*' * 20
print "#" * 20
# use function
pstar()
prstar()
标题行由def关键字,函数的名字,以及参数的集合(如果有的话)组成
def子句的剩余部分包括了一个虽然可选但是强烈推荐的文档字符串,和必须的函数体
调用函数
同大多数语言相同,python用一对圆括号调用函数
如果没有加圆括号,只是对函数的引用
>>> def foo():
... print "hello"
...
>>> foo()
hello
>>> foo
<function foo at 0x7ff2328967d0> # 函数在内存中的地址。
函数的返回值
多数情况下,函数并不直接输出数据,而是向调用者返回值
函数的返回值使用return关键字
没有return的话,函数默认使用None
>>> def foo():
... res = 3 + 4
>>> i = foo()
>>> print i
None
函数参数
定义参数
形式参数
- 函数定义时,紧跟在函数名后(圆括号内)的参数被称为形式参数,简称形参,由于它不是实际存在变量,所以又称虚拟变量
#!/usr/bin/env python
def pstar(num):
return '*' * num
n = int(raw_input("number: "))
print pstar(n)
实际参数
- 在主调函数中调用一个函数时,函数名后面括弧中的参数(可以是一个表达式)称为“实际参数”,简称实参
传递参数
调用函数时 ,实参的个数需要与形参个数一致
实参将依次传递给形参
>>> def foo(x,y):
... print 'x=%d,y=%d' %(x,y)
...
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 2 arguments (0 given)
>>> foo(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 2 arguments (1 given)
>>> foo(3,4)
x=3,y=4
位置参数
与shell脚本类似,程序名以及参数都以位置参数的方式传递给python 程序
使用sys模块的argv列表接收
$ vim args.py
#!/usr/bin/env python
import sys
print sys.argv
$ python args.py hello world
['args.py', 'hello', 'world']
#!/usr/bin/env python
# coding: utf-8 --
import sys
def cp(sfname,dfname):
src_fobj = open(sfname)
dst_fobj = open(dfname,'w')
while True:
data = src_fobj.read(4096)
if not data:
break
dst_fobj.write(data)
src_fobj.close()
dst_fobj.close()
cp(sys.argv[1],sys.argv[2])
默认参数
默认参数就是声明了默认值的参数
因为给参数赋予了默认值,所以在函数调用时,不向该参数传入值也是允许的
>>> def pstar(num = 30):
... print "*" * num
...
>>> pstar()
******************************
>>> pstar(40)
****************************************
将cp 编程函数形式:
#!/usr/bin/env python
# coding: utf-8 --
def cp(sfname,dfname):
src_fobj = open(sfname)
dst_fobj = open(dfname,'w')
while True:
data = src_fobj.read(4096)
if not data:
break
dst_fobj.write(data)
src_fobj.close()
dst_fobj.close()
cp('/bin/ls','/home/list')
cp('/bin/touch','/home/mytouch')
模块
定义模块
模块基本概念
模块是从逻辑上组织python代码的形式
当代码量变得相当大的时候,最好把代码分成一些有组织的代码段,前提是保证它们的彼此交互
这些代码片段相互间有一定的联系,可能是一个包含数据成员和方法的类,也可能是一组相关但彼此独立的操作函数
创建模块
模块物理层面上组织模块的方法十文件,每一个以.py作为极为的python文件都是一个模块
模块名称切记不要与系统中已存在的模块重名
模块文件名字去掉后面的扩展名(.py)即为模块名
使用模块
导入模块(import)
使用import导入模块
模块被导入后,程序会自动生成pyc的字节码文件以提升性能
模块属性通过“模块名.属性”的方法调用
如果仅需要模块中的某些属性,也可以单独导入
>>> import tab
>>> import sys
>>> import os,string
>>> string.digits
'0123456789'
>>> from random import randint #导入模块中的某个方法
>>> randint(1,10)
3
>>> import random as rdm #导入random 模块并加别名 rdm
模块加载(load)
一个模块只被加载一次,无论它被导入多少次
只加载一次可以阻止多重导入时代码被多次执行
如果两个文件相互导入,阻止了无限的相互加载
模块加载时,顶层代码会自动执行,所以只将函数放入模块的顶层是良好的编程习惯
模块导入的特性
模块具有一个__name__特殊属性
当模块文件直接执行时,__name__的值为‘__main__'
当模块被另一个文件导入时,__name__的值就是该模块的名字
$ cat foo.py
#!/usr/bin/env python
print __name__
$ cat bar.py
#!/usr/bin/env python
import foo
$ python foo.py
__main__
$ python bar.py
foo
__name__ 是python 的内部变量,在foo 中 打印 __name__ ,单独执行时,输出的名字是__main__,被其他程序导入后,显示foo。
一个模块文件自己独立执行的时候,__name__,打印的是__main__,如果是被其他文件导入了。则__name__打印的就是模块名
应用:
#vim star.py
#!/usr/bin/env python
def pstar(num=20):
return '*' * num
if __name__ == '__main__':
print pstar()
print pstart(40)
上述代码,单独执行(python star.py) ,则会执行 print pstar() print pstar(),如果import star,则不会执行print pstar() print pstar()
练习:生成8位随机密码
1、编写一个能生成8位随机密码的程序
2、使用random的choice函数随机取出字符
3、用于密码的字符通过string模块获得
4、改进程序,用户可以自己决定生成多少位的密码
多线程 ping
mtping.py
#!/usr/bin/env python
import os
import threading
def ping(ip):
result = os.system("ping -c2 %s > /dev/null" % ip )
if not result:
print "%s:up" % ip
else:
print "%s:down" % ip
if __name__ == '__main__':
for i in range(1,255):
ipaddress = "192.168.2.%s" % i
t = threading.Thread(target=ping,args=[ipaddr])
t.start()