进阶

Learn from: 廖雪峰网站

  • 判断一个对象是否是可迭代对象(即是否可用 for in 循环):通过collections模块的Iterable类型判断:
>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
  • for循环可同时引用两个变量

  • string类型可通过.lower() 来小写字符串中的字符

  • map() 函数: 将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回

>>> def f(x):
...     return x * x
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
  • reduce把一个函数作用在一个序列[x1, x2, x3, …]上,该函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算:
#把序列[1, 3, 5, 7, 9]变换成整数13579
>>> from functools import reduce
>>> def fn(x, y):
...     return x * 10 + y
>>> reduce(fn, [1, 3, 5, 7, 9])
13579
  • 高阶函数可以把某函数作为结果值返回:如return sum。 在这种情况下,只有最终调用函数时才会计算,否则返回的只是一个函数,且返回的函数保存了相关的参数和变量,这种程序叫 ”闭包(Closure)“

模块

  • Python模块的标准文件模板:
    • 第1行和第2行是标准注释,第1行注释让hello.py文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身使用标准UTF-8编码;
    • 第4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;
    • 使用__author__变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

' a test module '

__author__ = 'Michael Liao'

import sys

def test():
    args = sys.argv
    if len(args)==1:
        print('Hello, world!')
    elif len(args)==2:
        print('Hello, %s!' % args[1])
    else:
        print('Too many arguments!')

if __name__=='__main__':
    test()
  • 在Python中,安装第三方模块,是通过包管理工具pip完成的(windows下)。

  • 模块搜索路径:

    • 搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中
    • 添加自己的搜索目录:
      • 直接修改sys.path,添加要搜索的目录:
        >>>sys.path.append('/Users/michael/my_py_scripts')

    这种方法是在运行时修改,运行结束后失效

      • 设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。

关于安装 module 的问题:

由于我的不能直接用 pip install 安装软件,于是用以下方法:

>>> import pip
>>> pip.main(['install', 'numpy'])

Since pip is a module in standard library, but it isn’t a built-in function(or module), so we need to import it.


  • 要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list
  • __xxx__ 在Python中表示特殊变量
  • @property装饰器负责把一个方法变成属性调用
class Student(object):

    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value
  • MixIn:给一个类增加多个功能,实现多重继承
  • type()函数可以创建类
  • 错误机制:try...except...finally...
try:
    print('try...')
    r = 10 / int('a')
    print('result:', r)
except ValueError as e:
    print('ValueError:', e)
except ZeroDivisionError as e:
    print('ZeroDivisionError:', e)
finally:
    print('finally...')
print('END')
  • logging模块可以记录错误信息, 输出的信息有几种级别:debuginfowarningerrorlogging.info() 输出一段文字:
import logging
logging.basicConfig(level=logging.INFO)
  • 可使用assert调试, 启动Python解释器时可以用-O参数来关闭assert
  • 单步调试:启动Python的调试器pdb,输入命令 l 来查看代码,输入命令 n 可以单步执行代码,输入命令p 变量名来查看变量,输入命令q结束调试,退出程序:
 python3 -m pdb err.py
 > /Users/michael/Github/learn-python3/samples/debug/err.py(2)<module>()
-> s = '0'
  • 或,import pdb,然后,在可能出错的地方放一个pdb.set_trace(),设置一个断点
  • StringIO, 在内存中读写str
  • BytesIO 在内存中读写 二进制数据

正则表达式

  • 字符串匹配:
    • \d匹配一个数字:'00\d'可以匹配'007',但无法匹配'00A'
    • \w匹配一个字母或数字:'\w\w\d'可以匹配'py3'
    • . 匹配任意字符
  • 匹配变长的字符:
    • *表示任意个字符(包括0个)
    • ?表示0个或1个字符
    • {n}表示n个字符
    • {n,m}表示n-m个字符
    • \d{3}\s+\d{3,8}\d{3}表示匹配3个数字,例如'010'\s可以匹配一个空格(也包括Tab等空白符),所以\s+表示至少有一个空格,例如匹配’ ‘,’ ‘等;\d{3,8}表示3-8个数字,例如’1234567’
  • 精确地匹配,可以用[]表示范围:
    • [0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线;
    • [0-9a-zA-Z\_]+可以匹配至少由一个数字、字母或者下划线组成的字符串,比如’a100’,’0_Z’,’Py3000’等等;
    • [a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是Python合法的变量;
    • [a-zA-Z\_][0-9a-zA-Z\_]{0, 19}更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。
    • A|B可以匹配A或B,所以(P|p)ython可以匹配’Python’或者’python’
    • ^表示行的开头,^\d表示必须以数字开头。
    • $表示行的结束,\d$表示必须以数字结束。
  • re 模块
    • match()方法判断是否匹配,如果匹配成功,返回一个Match对象,否则返回None
>>> import re
>>> re.match(r'^\d{3}\-\d{3,8}$', '010-12345')
  • 切分字符串
>>> re.split(r'[\s\,\;]+', 'a,b;; c  d')
['a', 'b', 'c', 'd']
  • 分组
    • ()表示的就是要提取的分组(Group)
    • 如果正则表达式中定义了组,就可以在Match对象上用group()方法提取出子串来。注意到group(0)永远是原始字符串
>>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
>>> m
<_sre.SRE_Match object; span=(0, 9), match='010-12345'>
>>> m.group(0)
'010-12345'
>>> m.group(1)
'010'
>>> m.group(2)
'12345'
  • 贪婪匹配
    • 正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。
    • 加个?就可以让\d+采用非贪婪匹配:
>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')
>>> re.match(r'^(\d+?)(0*)$', '102300').groups()
('1023', '00')

你可能感兴趣的:(python,python)