Python 快速入门 – 模块与输入输出

模块

  • 一个python文件,以.py结尾,包含了对象定义和可执行语句
    • 模块能定义函数,类和变量,模块里也能包含可执行的代码
    • 更有逻辑和层次地组织python代码
    • 相关的代码进行单独的组织会使代码更容易理解并被复用
    • 模块的模块名(字符串)可以由全局变量__name__得到
    • python module.py时,其__name__被设置 为”__main__

import语句

  • import语句应该放在模块的初始位置
  • 当解释器遇到import语句时,如果模块在当前的搜索路径就会被导入
    • 搜索路径为当前目录或存储在sys.path的路径
      • 首先在当前目录进行搜索
      • sys.path.append()
  • 可通过模块名称来访问模块成员
    • 如果频繁使用一个函数,则可以将之赋给本地变量
    • sf = sys.f
  • 模块在解释器会话中只导入一次
    • 如果更新,需要重启解释器或者重新加载
import imp
imp.reload(modulename) #交互式情况下可能会用到

from ... import语句

  • 从模块导入指定的部分到当前的命名空间
  • 既可以是子模块(甚至子包),也可以是函数、 类或变量等
  • from ... import *
    • 导入所有部分
    • 除下划线( _ )开头的命名
    • 不建议过多使用(低效繁杂)

可执行语句

  • 模块可以包含可执行语句
  • 这些语句一般用来初始化模块,其仅在第一次被导入的地方执行一次
  • jieba导入时的打印信息

全局变量

  • 模块私有符号表,并被模块内所有的函数作为 全局符号表使用
  • 模块内部可以使用全局变量,而无需担心与其他模块全局变量冲突
  • 可通过模块访问其全局变量modname.itemname

模块加载

加速

  • __pycache__目录下以 module.version.pyc 名字缓存模块编译后的版本
  • 编译后的模块是跨平台的
  • 解释器会检查源文件与编译版本的修改日期以 确定是否过期并需要重新编译
    • 如果没有源文件则不会检查缓存
  • 若支持没有源文件(只有编译版)的程序发布, 则编译后的模块必须在源目录下且不包含源文 件

优化

  • 为了减少编译模块的大小,可在Python命令 行中使用-O或者-OO“优化”
    • -O参数删除了断言语句
    • -OO参数删除了断言语句和 __doc__字符串
  • 缓存文件名会发生变化
    • 包括opt等优化标记
  • 仅在确定无误的场合使用这一选项
    • 并非加速代码的执行速度
    • 程序逻辑可能依赖__doc__
  • compileall为指定目录的所有模块创建缓存
    • python -m compileall目录

dir()函数

  • dir()
    • 按模块名搜索模块定义并返回一个字符串类型的命名列表
    • 无参数调用时,dir()函数返回当前模块定义的命名

  • 模块集,结构化的模块命名空间
    • 圆点.
    • A.B的模块表示了名为A的包中名为B的子模块
  • 避免模块之间的命名冲突
  • 通过分层的文件体系来组织
    • 为了让Python将目录当做内容包,必须包含__init__.py文件
    • 一般空白即可
    • 可以执行包的初始化代码
    • __all__变量

包的导入

– 可只导入包里的特定模块
import a.b.c
通过完整的名称来引用
a.b.c.fun()
from a.b import c
c.fun()
from a.b.c import fun
fun()
  • from package import *
    • 如果包中的 __init__.py代码定义了一个名 为__all__的列表,就会按照列表中给出的模 块名进行导入
    • 如果没有定义__all__,则不会导入所有子模块

包内引用

  • from module import name 来显式地从相对位置导入
  • 用点号标明关联导入当前和上级包
    • from . import b当前目录
    • from .. import d上一级目录
    • from ... import e

命名空间

三种类型

  • 内置名称(built-in names)
    • Python语言内置的名称,比如函数名abs和异常名 称Exception等
  • 全局名称(global names)
    • 模块中定义的名称,如函数、类、其它导入的模块、模块级的变量和常量等
  • 局部名称(local names)
    • 函数中定义的名称,如函数的参数和局部变量等, 或类中定义的函数及变量等
  • 查找顺序
    • 局部的命名空间->全局命名空间->内置命名空间

命名空间的生命周期

  • 命名空间的生命周期取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期就结束
  • Python 中只有模块、类和函数才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)并不会引入新的作用域
    • 在这些语句内定义的变量,在代码块外也可访问
    • 与c语言是否一样?

四种作用域

  • L(Local)
    • 最内层,包含局部变量,比如一个函数或方法内部
  • E(Enclosing)
    • 包含了非局部(non-local)也非全局(non-global)的变量, 比如嵌套函数等,一个函数A 中包含了另一个函数B,那么对 于B,A中的作用域就为 nonlocal
  • G(Global)
    • 当前模块的最外层,比如当前模块的全局变量
  • B(Built-in)
    • 包含了内建的变量/关键字等
  • 搜索规则顺序
    • L –> E –> G –>B

虚拟环境和包

虚拟环境

  • Python应用程序经常会使用一些不属于标准库的包和模块,或者应用程序有时候需要某个特定版本的库
  • 导致无法安装一个Python来满足每个应用程 序的要求
  • 创建一个虚拟环境(通常简称为 “virtualenv”),包含一个特定版本的 Python,以及一些附加的包的独立的目录树

pyvenv

  • 指定安装一个特定的版本的Python
  • 或选择一个指定的Python版本 –pyvenv 虚拟环境目录
  • pyvenv目录
    • 会创建一个目录,并且也在目录里面创建一个包含Python解释器,标准库,以及各种配套文件的 Python “副本”
  • 激活环境
    • win: Scripts/activate
    • linux/unix: source /bin/activate
    • 激活虚拟环境会改变shell提示符,显示正在使用的虚拟环境
  • 可以使用pip进行对应版本的包管理

输入输出

format函数

  • 通过位置
  • 通过关键字参数
print('a1 = {} a2= {} a3= {}'.format('first','second','third'))
print('a1 = {1} a2= {0} a3= {2}'.format('first','second','third'))
print('your name is {name} , age is {age}'.format(age=87,name='jack’))
------------------
a1 = first a2= second a3= third
a1 = second a2= first a3= third
your name is jack , age is 87 
  • 通过对象属性
class Person(object):
    address = '中国'  # 类属性,没个实例的公共属性
    def __init__(self, name, sex, age):  # 相当于java中的构造方法
        self.name = name  # 实例属性
        self.sex = sex  # 实例属性
        self.age = age  # 实例属性
p = Person('Steve', 'M', 21)
print('name = {p.name} age = {p.age}'.format(p=p))
--------------------
name = Steve age = 21
dt = {'k1': 1, 'k2': 2, 'k3': 3}
print('k1: {0[k1]:d}; k2: {0[k2]:d}; k3: {0[k3]:d}'.format(dt))
print('k1: {k1:d}; k2: {k2:d}; k3: {k3:d}'.format(**dt))
---------------------
k1: 1; k2: 2; k3: 3
k1: 1; k2: 2; k3: 3 
  • 通过下标
    • print('{0[1]} {0[2]} {1[2]} {1[0]}'.format(s1,s2))

格式化输出

  • 对齐与填充
    • print('{0:10} ==> {1:10d}'.format(name, number))
  • 浮点小数输出
    • print('常量 PI 的值近似为 {0:.3f}。'.format(math.pi))
  • 进制及其他显示
    • b : 二进制
    • d :十进制
    • o :八进制
    • x :十六进制
    • !s :将对象格式化转换成字符串
    • !a :将对象格式化转换成ASCII
      • print(’{!a}’.format(‘天津tianjin’))
    • !r :将对象格式化转换成repr

序列化与反序列化

  • 序列化(serialization):将程序中的对象保存到文件中以永久存储
  • 反序列化(deserialization):从文件中创建上一次程序保存的对象

pickle

import pickle
#文件
pickle.dump(obj, file[, protocol])
pickle.load(file)
#字符串
pickle.dumps(obj[, protocol])
pickle.loads(string)

json

import json
#文件
json.dump(f)
json.load(f) – #字符串
json.dumps() – json.loads()

文件操作

  • os模块
    • 目录遍历
    • 文件是否存在
  • shutil模块
    • 文件移动
    • 文件删除
    • 文件复制
  • zipfile模块
    • 压缩文件读取或存储
class person(object):
   address = '中国'  # 类属性,没个实例的公共属性
   def __init__(self, name, sex, age):  # 相当于java中的构造方法
       self.name = name  # 实例属性
       self.sex = sex  # 实例属性
       self.age = age  # 实例属性
   def dance(self):  # 方法
       print(self.name, '跳了一场舞')
hong = person('小红', '女', 18)  # 实例化小红,将实例化的对象赋值给变量hong
ming = person('小明', '男', 26)
hua = person('小花', '女', 22)

Related Posts