Python 编程快速上手


       2012 下半年, 想学一种新的编程语言吗? 选择 Python 吧!        


       学习一门新语言, 有两种方式: 1.   怀空杯心态, 尽量使用该语言的地道表达方式, 避免受原有语言思路的影响; 2. 将新语言与原有语言关联对比, 从而在最快时间内能够掌握基础知识,编写出有用的程序。一般这种情况下,是项目需求所致。 


        学习Python 有如下理由: 1.  表达能力强大, 不逊于C,C++,JAVA这些主编程语言 这是必要条件; 2.  它是类脚本语言, 这意味着简化了程序的编写, 用更少的代码完成用主编程语言可能语法繁琐的各种任务; 3.  格式严谨, 有利于代码风格的训练和软件代码的可读性,项目代码的管理;  4.  库、框架多,可以快速建立应用。  有此四条足矣,赶紧上路吧,别比来比去了!


        我采用的思路是将 Python 与 Java 关联起来, 学习 Python  基础. 所以,本文不打算细述 Python 的语法, 而是通过对比差别来增强对Python 的认识, 当然, 大量的编程练习是必要的,最好能够结合一个小项目,并通过不断试错。 我是通过公司的一个实际项目边学边用而学习使用 Python 的。


        1.    Python  的代码缩进: 这是首先要提到的。 用括号括起来的代码块, 将通过 冒号加 正确缩进(同一层次的代码块必须使用完全相同的缩进) 来表达 , 条件语句中的括号通常可省略。 语句末的分号可有可无。写python 代码块时一定要注意加上冒号和正确的缩进, 这是经常容易犯的错误。例如:               

while ( i < 100) {

         i += 2

         printf("%d",x)

 }   

      用  python  写是这样:        

while  i < 100 :
    i += 2    // 这里正确的缩进是必要的,否则报语法错误。
    # print x    ## Error:  unexpected indent , 同一层次的代码必须采用完全相同的缩进, 多一个或少一个空格都不行。

         2.      变量在使用前一定要进行初始化和赋值,否则解释器无法识别该变量。一个变量均可以存储多种类型的值,不强调类型。 函数定义时不强调类型。 这是脚本语言的特点, 方便程式的编写。 比如       

def func(x) :
    return x*2

x = 2
y = func(x) 
print x , " ", y
x = ' now changed to an string '
print x, "  " , y  , ' OMG'          #  松散的打印格式 ,  双引号和单引号均可表示字符串 
# print zzz    会报错:  NameError : name 'zzz' is not defined.        

 

      3.    控制流 :  if , if-elif-...-else , for ... in ... , while ,  continue, break  ;  还有一个 pass 语句表示空执行, 即相当于空块,或者 NOP 

      4.   单行注释用 # 号, 多行注释用三个单引号           

 '''     these are 
             more lines.
 '''

     

          5.    强大的内置动态数据结构: list ,  set,  tuple,  dictionary .  list 主要方法有: append(x) , extend(List), insert(x),  sort(), reversed(),  pop([i]), insert(i, x), 等。 这些动态的数据结构很容易组合成更强大的数据结构工具。 关于这些结构的使用,网上有很多文章,这里就不细述了。                 

mylist = [ ]   #  建立空列表  
mylist = [1 , 3 , 'good']
print mylist
mylist[1] = [('this is a tuple'),  ['nested list']]
print mylist

   set 有成员检测功能:

   

myset = [1 , 2 ,1 ,1 , 2]   # 建立集合  ===> myset = [1 ,2]  
x = 1    
if x in myset :   
    print myset, " has member : ", x
else:
    print x , " is not found in ", myset 
mydict = {1 : ('zs', 'good', 25) , 2 : ('ww', 'right', 30) }
print mydict
mydict['city'] = 'hangzhou'
for k, v in  mydict.iteritems() :
    print  k, v
print mydict.keys()

        元组 tuple 与列表类似, 但元组是不可变的, 这意味着无法修改元组的值。 引用元组的值采用下标方式     

mytuple = (1, 2, 3, 4)
print mytuple[2]
# Error  :  mytuple[0] = 0

 

         6.   模块。 一个 python 文件就是一个模块, 以 .py 为后缀。 当你在 func.py 中编写了函数 sign(x) 后, 要在其他文件中引用,则采用如下方式:

                     [1]  import  func

                           func.sign(x)   #  模块名.函数名

                     [2]  from func import sign(x)

                           sign(x)           # 直接引用

 

         7.   作用域。  这里主要给出一个基本的理解。 如上所述,

         a.  一个 Python 文件就是一个模块,该模块的变量的作用域主要可分为全局作用域,本地作用域以及内置作用域。

         b.  代码块(例如, try块,if-else, for , while 等),函数中定义的变量,方法,类等属于本地作用域, 可以通过 locals() 查询,作用范围在创建时到代码块或函数退出为止; 函数之外的变量,方法,类等属于全局作用域,作用范围从创建时到整个文件末尾为止,可以通过 globals() 查询。

         c.  当全局作用域的变量与本地作用域的变量冲突时,会优先采用本地作用域中的变量,查找不到时再到全局作用域中查找。要使用全局作用域的变量,必须先声明 global var.  声明global var 之前不能出现同名变量 var.  请看:

           x = 2

           def fun1() : 

                 x = 3

                 print  "[1] x = " , x    // 使用局部变量x  打印 [1]  x = 3 

           print "init: x = " , x        // 使用全局变量x   打印 init x = 2  

           fun1()

           print "after [1] x = ", x   // 不会改变全局变量x  打印 after [1] x = 2 

           def fun2() : 

                 global  x     // 声明使用全局变量 x 

                  x = 3

           fun2()

           print "after fun2 : x = ",  x     // 打印  after fun2: x = 3

           def fun3() :

                 x = 0

           #ERROR    global x    : 语法错误: x 不能既是全局变量又是局部变量。也就是说,      

           print "[3] x = ", x            : 要使用全局变量,不可以出现在同名的局部变量之后。

           fun3()

        内置作用域是python 语言所定义的系统变量,方法,类等的作用域, 可以直接使用。  例如, type 函数可以打印对象的类型。 

           print type(x)      // 打印  <type 'int'>

           def type(x) :

                 print "my type(): "

                 return x*2

           print type(x)     // 打印 6

          因此,可以得到又一条结论: 如果定义了与内置方法同名的方法, 会优先采用自定义的方法。 事实上, 作用域的优先级:

          本地作用域  》  全局作用域 》 内置作用域

  

        8.  异常机制。 try-except , try-except-else,  try-finally,  try-except-finally 四种。 


        9.   if  __name__ == '__main__' :    do something ;  __name__ 是python模块的内置属性。每个python模块都是一个.py文件,既可以从命令行运行,又可以导入其他模块。当从命令行运行时,__name__ == ‘__main__’ , do something 会执行; 当导入其他模块时, __name__ 的值为模块的名称, 不等于‘ __main__ ’, do something 不会执行。也就是说,该模块存在某些语句,当自身单独运行时,期望被执行,而作为支持模块导入其他模块时,却不希望执行。  因此, 这条语句通常可用于单独运行和测试该模块。 

        

        10.  下面的例子演示了Python 提供的一些基本语言特性: 缩进,内置数据结构, 控制流, 读写文件,重定向, 导入模块, 类定义, 异常机制,日志,正则表达式。代码本身没有什么创新之处,但整合到一起,可以演示Python 的大部分基本语言特性。 

        dupkeys.py

 
##################################################################
#
#  validate if the input text file contains duplicated keys.
#  the input.txt should like below:
#      key1  value1
#      key2  value2
#  ...
#
#  the result is stored into a hashtable:
#     {key: [count, [value1, value2,..,valueN]]} 
#
##################################################################

import sys
import re
from thelog import initlog
from exc import NotMatchedException

patt = re.compile(r'^\s*(\w+)\s+(\w+)[\s\r\n]+$')
total_items = 0
count = { }
def proc(line) :
    matched = patt.match(line)
    try :
        if matched :
            global total_items
            total_items += 1
            key = matched.group(1)
            value = matched.group(2)
            if key in count :
                valuelist = (count[key])[1]
                valuelist.append(value)
                count[key] = [(count[key])[0]+1, valuelist]
            else :
                count[key] = [1, [value]]
        else :
            raise NotMatchedException('The line Not matched:  %s' % line)
    except (NotMatchedException, Exception), args:      
        dupkeysLog.error(args)


if len(sys.argv) != 2 :
    print "usage: python dupkeys.py filename.txt "
    sys.exit(1)

logfile = 'dupkeys.log'
dupkeysLog = initlog(logfile)

resfile = open('result.txt', 'w')

sysStdout = sys.stdout
sys.stdout = resfile  # redirect stdout into file result.txt  

filename = sys.argv[1]
inputfile = open(filename)

for line in inputfile :
    proc(line)

print "total items in file %s : %d" % (filename, total_items)
dupkeysLog.error("Keys duplicated: ")
for k, v in count.iteritems() :
    print k, v
    if v[0] > 1 :
        dupkeysLog.error( ' %s %s ' % (k, v) )

if inputfile:
    inputfile.close()    

if resfile :
    resfile.close()

sys.stdout = sysStdout

 

       thelog.py

import logging

LOG_LEVELS = {
            'DEBUG': logging.DEBUG, 'INFO': logging.INFO, 
            'WARN': logging.WARNING, 'ERROR': logging.ERROR,
        'CRITICAL': logging.CRITICAL
     }

def initlog(filename) :

    logger = logging.getLogger()
    hdlr = logging.FileHandler(filename)
    formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
    hdlr.setFormatter(formatter)
    logger.addHandler(hdlr)
    logger.setLevel(LOG_LEVELS['ERROR'])

    return logger


if  __name__ == '__main__' : 
    errlog = initlog("errlog.log")

    errlog.info('this is an ordinary info')
    errlog.warn('this is a warning')
    errlog.error('this is an error that should be handled')
    errlog.critical('this is an severe error')

  

     exc.py 

class MyException(Exception) : pass

class MsgException(MyException) :

    def __init__(self, msg) :
        self.msg = msg

    def __str__(self) :
        return repr(self.msg)

class NotMatchedException(MsgException) : pass
                 

 

posted @ 2012-07-20 22:07  琴水玉  阅读(317)  评论(0编辑  收藏  举报