作为一个有多年Java开发经验的老程序员,最近却被python精练的语法迷住了。同时发现python语言在云计算、系统运维领域确实用得很多,感觉有必要把python这门语言学一学。以下记录了学习过程中的关键点以备忘。

语言关键点

  • 数字特殊计算符号

    print 4**3
    print 17//3.0
    
  • 复数支持

    print 3+4j
    print (3+4j).real
    print (3+4j).imag
    print abs(3+4j)
    
  • 字符串

    print 'abcdef'
    print r'abc\ndef'
    print '''abc
    def
    ghi
    '''
    print 'abc\
    def\
    ghi'
    'abc'+'def'
    'abc'*3
    
  • unicode与str之间相互转换

    print u'中国'
    unicodestr=u'中国'
    utf8str=unicodestr.encode('utf-8')
    unicodestr2=utf8str.decode('utf-8')
    
  • list与slice

    list1=[1, 2, 3, 4]
    print list1[3]
    print list1[1:]
    print list1[:3]
    print list1[::2]
    
  • 流程控制

    if a<b:
    print a
    elif a==b:
    print a
    else:
    print b
    
    list1=[1, 2, 3, 4]
    for num in list1:
    print num
    
    for idx in range(len(list1)):
    print idx
    
    for (idx, num) in enumerate(list1):
    print idx, num
    
    for num in list1:
    if num==3:
    break
    
    for num in list1:
    if num==3:
    continue
    
    print num
    
    while running:
    print 'alive'
    
    if 3==3:
    pass
    
  • 函数相关

    def fun1(a, b):
    print a+b
    
    def fun2(a, b=4):
    print a+b
    
    def cheeseshop(kind, *arguments, **keywords):
    pass
    
    cheeseshop("Limburger", "It's very runny, sir.",
           "It's really very, VERY runny, sir.",
           shopkeeper='Michael Palin',
           client="John Cleese",
           sketch="Cheese Shop Sketch")
    
    pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
    pairs.sort(key=lambda pair: pair[1])
    
    def fun3(a, b)
    '''Calculate a+b
    
    Comment here
    '''
    pass
    
  • list作为堆栈

    stack=[3, 4, 5]
    stack.append(6)
    print stack.pop()
    
  • 队列

    from collections import deque
    queue = deque([3, 4, 5])
    queue.append(6)
    queue.popleft()
    
  • filter, map, reduce

    filter(lambda x: x%3==0 or x%5==0, range(1, 100))
    
    map(lambda x: x*2, range(1, 10))
    
    reduce(lambda x, y: x+y, range(1, 10))
    
  • 列表推导

    [num*2 for num in range(1, 10) if num%4!=0]
    
  • 删除变量、删除list子项

    a=3
    b=a
    del a
    
    list1=[1,2,3,4,5]
    del list1[3]
    del list1[:]
    
  • tuple元组

    t = 12345, 54321, 'hello!'
    
    a, b=b,a
    
  • set集合

    
    fruit = set(['apple', 'orange', 'apple', 'pear', 'orange', 'banana'])
    print 'orange' in fruit
    
    a={'a', 'b', 'c'}
    
    a = set('abracadabra')
    b = set('alacazam')
    print a-b
    print a|b
    print a&b
    print a^b
    
  • set集合推导式

    print {x for x in 'abracadabra' if x not in 'abc'}
    
  • dict字典

    tel = {'jack': 4098, 'sape': 4139}
    
    dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
    
    dict(sape=4139, guido=4127, jack=4098)
    
  • dict字典推导式

    {x: x**2 for x in (2, 4, 6)}
    
  • 模块

    print __name__
    import sys
    print sys.path
    print sys.argv
    
  • 格式化输出

    print '%d + %d = %d' % (3, 4, 5) //不建议使用这种旧的语法
    
    print '{} + {} = {}'.format(3, 4, 5)
    
    print '{0} + {1} = {2}'.format(3, 4, 5)
    
    print '{num1} + {num2} = {num3}'.format(num1=3, num2=4, num3=5)
    
    print '{num1:.2f} + {num2:.2f} = {num3:.2f}'.format(num1=3, num2=4, num3=5)
    
    print '{num1:4d} + {num2:4d} = {num3:4d}'.format(num1=3, num2=4, num3=5)
    
    from string import Template
    print Template('$who likes $what').substitute(who='tim', what='kung pao')
    
    tel = {'jack': 4098, 'sape': 4139}
    print json.dumps(tel, indent=2)
    
  • 文件读写

    f=open('/somewhere/filename', 'w')
    
    f.read()
    
    for line in f:
    print line,
    
    f.close()
    
  • json处理

    import json
    
    f=open('/somewhere/filename', 'w')
    
    tel = {'jack': 4098, 'sape': 4139}
    json.dumps(tel, f)
    f.close()
    
    f=open('/somewhere/filename', 'r')
    x=json.load(f)
    
  • 异常

    try:
    pass
    except ValueError as e:
    pass
    finally:
    pass
    
    def fun1():
    raise ValueError('something')
    
    class MyError(Exception):
    def __init__(self, value):
    self.value = value
    def __str__(self):
    return repr(self.value)
    
  • with语法

    with open('/somewhere/filename', r) as f:
    for line in f:
    print line,
    
  • 类的定义

    class MyClass(BaseClass):
    
    pubPro=None
    
    def __init__(self, arg1):
    BaseClass.__init__(self)
    self.arg1 =
    
    def pubFun1(self, arg1, arg2):
    pass
    
    def __priFun1(self, arg1):
    pass
    
    cls=MyClass('hello')
    print type(cls)
    print cls.__class__
    
  • 生成器

    def reverse(data):
    for index in range(len(data)-1, -1, -1):
    yield data[index]
    
    for char in reverse('golf'):
    print char
    
  • 标准库

    import os
    print os.getcwd()
    os.chdir('/somewhere')
    os.system('ping -c 4 127.0.0.1')
    
    import shutil
    shutil.copyfile('/somewhere/filename', '/anotherwhere/filename')
    
    import glob
    print glob.glob('*.py')
    
    import sys
    sys.exit(0)
    sys.stderr.write('err msg')
    sys.stdout.write('output msg')
    
    import re
    print re.findall(r'([a-z]+)', 'which foot or hand fell fastest')
    
    import math
    math.cos(math.pi / 4.0)
    math.log(1024, 2)
    
    import random
    random.choise(['apple', 'pear', 'banana'])
    random.sample(xrange(100), 10)
    random.random()
    random.randrange(6)
    
    import urllib2
    f=urllib2.urlopen('http://www.baidu.com')
    for line in f:
    print line,
    f.close()
    
    import smtplib
    smtpConn = smtplib.SMTP('stmp.qq.com')
    smtpConn.login('username', 'password')
    smtpConn.sendmail('fromuser@qq.com', 'touser@qq.com',\
    '''
    some long text
    ''')
    smtpConn.quit()
    
    from datetime import date
    now = date.today()
    time1 = date(2016, 8, 15)
    print now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")
    
    range1 = now - time1
    print range1.days
    
    import zlib
    s = b'witch which has which witches wrist watch'
    t = zlib.compress(s)
    zlib.decompress(t)
    
    import locale
    locale.setlocale(locale.LC_ALL, locale='zh_CN.UTF-8')
    locale.getlocale()
    locale.getdefaultlocale()
    
    import logging
    logging.debug('Debugging information')
    logging.info('Informational message')
    logging.warning('Warning:config file %s not found', 'server.conf')
    logging.error('Error occurred')
    logging.critical('Critical error -- shutting down')
    

练手

使用编程语言完成一个简单的任务是学习某个语言最快捷的办法,于是我想了一个简单任务:通过抓取页面自动从ishadowsocks.com上得到一个shadowsocks服务器的连接信息,并更新本机shadowsocks-libev服务的配置文件,再自动重启shadowsocks-libev服务。如果再配合cron定时执行脚本,基本可以做到免费的翻墙方案。源代码如下:

#!/usr/bin/env python
# coding: utf-8

import urllib
import re
from lxml import etree
import json
import os

# 请求www.ishadowsocks.org服务器, 获取shadowsocks服务器信息
content = ''
f = None
try:
    f = urllib.urlopen('http://www.ishadowsocks.org/')
    content = f.read()
finally:
    if f is not None:
        f.close()

tree = etree.HTML(content)
nodes = tree.xpath('//*[@id="free"]/div/div[2]/div[3]/h4')
addr = ''
port = 0
pwd = ''
method = ''
for node in nodes:
    txt = node.text
    if type(txt) is unicode:
        utf8str = txt.encode('utf-8')
        ret = re.findall(r'^.*服务器地址:(.*)$', utf8str)
        if len(ret) > 0:
            addr = ret[0]
        ret = re.findall(r'^端口:(.*)$', utf8str)
        if len(ret) > 0:
            port = int(ret[0])
        ret = re.findall(r'^.*密码:(.*)$', utf8str)
        if len(ret) > 0:
            pwd = ret[0]
        ret = re.findall(r'^加密方式:(.*)$', utf8str)
        if len(ret) > 0:
            method = ret[0].lower()

# 生成shadowsocks-libev配置文件
config = {
    "server": addr,
    "server_port": port,
    "local_port": 1080,
    "password": pwd,
    "timeout": 600,
    "method": method
}

configstr = json.dumps(config, indent=2)

with open('/tmp/shadowsocks-libev.json', 'w') as f:
    f.write(configstr)
    f.write('\n')

# 重启shadowsocks-libev服务
os.system('launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.shadowsocks-libev.plist')
os.system('launchctl load ~/Library/LaunchAgents/homebrew.mxcl.shadowsocks-libev.plist')

下一步计划

在kindle上买了本python cookbook,下一步计划把这本书先看完。