Python 佛脚不好抱 - 模块与输入输出

本文详细介绍了Python中的模块概念,包括import语句、from...import的使用,以及模块加载的加速和优化。同时,讨论了包的组织、命名空间的类型和作用域规则。此外,还讲解了输入输出的相关内容,如format函数、序列化与反序列化以及文件操作。
摘要由CSDN通过智能技术生成

模块

  • 一个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导入时的打印信息

全局变量待掌握[151]04NOTICE

  • 模块私有符号表,并被模块内所有的函数作为 全局符号表使用

  • 模块内部可以使用全局变量,而无需担心与其他模块全局变量冲突

  • 可通过模块访问其全局变量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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值