循环语句

    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()