Python学习笔记五(模块与包)

一、模块

1.模块介绍

一个模块就是包含了一组功能的python文件,可以通过import导入模块使用。

python中模块分为四个类别:

  a) 使用python编写的.py文件

  b) 已被编译为共享库或DLL的C或C++扩展

  c) 把一系列模块组织到一起的文件夹,文件夹内有__init__.py文件,称该文件夹为包

  d) 使用C编写并链接到python解释器的内置模块

定义my_module.py模块,模块名为my_module

print("from my_module.py")
num = 2222
def read1():
    print("my_module模块:",num)
def read2():
    print("my_module模块")
    read1()
def change():
    global num
    num = 0

2.模块导入

模块可以包含可执行的语句和函数定义,这些语句目的是初始化模块,在模块名第一次遇到import语句时才执行。模块第一次导入后就将模块名加载到内存了,后续import次模块是对已加载到内存的模块对象增加了一次引用,不会重新执行模块内语句。

第一次模块导入时会做的三件事:

  a) 为模块源文件创建新的名词空间,在模块中定义的函数和方法若是使用global时访问的就是这个名词空间。

  b) 在新创建的命名空间中执行模块中包含的代码。

  c) 使用模块名创建名字来引用命名空间

每个模块都是一个独立的名称空间,定义在模块中的函数,把这个模块名称空间当做全局名称空间。不用担心自定义模块中全局变量被导入时与使用者全局变量冲突。

import  my_module
num = 111
print(my_module.num)  #输出的是模块全局名称空间中num的值
import  my_module
def read1():
    print("from test...")
my_module.read1()  #执行的是模块全局名称空间中的read1
import  my_module
num = 111
my_module.change()  #实际修改的模块自身全局名称空间中的num
print(num)          #输出的是调用函数全局名称空间中的num

可以使用import my_module as mm 为模块起别名,对编写可扩展代码有用。比如两个模块xmlreader.py和csvreader.py,都定义了函数read_data(filename)用来从文件中读取一些数据,但采用不同的输入格式。可以编写代码来选择性地挑选读取模块。

if file_format == "xml":
    import xmlreader as reader
elif file_format == "csv":
    import csvreader as reader
data = reader.read_date(filename)

from...import和import的区别:使用from...import...是将模块中的名字直接导入到当前的名称空间中,在当前名称空间中,直接使用相关名字即可,无需使用模块前缀。缺点是容易和当前执行文件中的名字冲突。

函数中调用的变量或其他函数,仍然在函数定义文件中的全局名称空间中找。

from my_module import read1
num = 1111
read1()  #调用read1时,仍然从my_module全局名称空间中找num
from my_module import read2
def read1():
    print("aaaa")
read2()   #仍然从my_module全局名称空间中找read1
from my_module import read1
def read1():
    print("aaaa")
read1()   #重名会覆盖,以本文件中定义为准,覆盖掉导入的

from...import *会吧模块中所有的不是以下划线开头的名字都导入到当前位置,一般不建议使用该方式。可以使用__all__控制*,比如在模块中新增一行__all__=[‘read1‘,‘read2‘] 使用from...import *就只能导入这两个名字。

3.py文件区分两种用途:模块和脚本

一个python文件的两种用途:

  a) 当做脚本执行:__name__=="__main__"

  b) 当做模块被导入使用:__name__=="模块名"

  可以控制.py文件在不同应用场景下执行不同的逻辑

4.模块搜索路径

模块查找顺序为:内存中已加载的模块-》内置模块-》sys.path路径中包含的模块

  a) 第一次导入模块时,会检查该模块是否已经被加载到内存(当前执行文件名称空间对应内存)中,有则直接引用。

    python解释器启动时会自动加载一些模块到内存,使用sys.module可以查看

  b) 如果内存没有,解释器会查找同名的内建模块

  c) 如果内建模块也没有,则从sys.path给出的目录列表中依次查找模块文件。

初始化后,python程序可以修改sys.path,路径在前面的优先于标准库被加载。通过列表添加的方式添加新路径。

import sys
sys.path.append("D:\\")
sys.path.insert(0,"E:\\")   #最前面优先被搜索到
print(sys.path)

二、包

1.包的介绍

包是一个包含有__init__.py的文件夹,用于组织python模块名称空间的方式。主要目的为提高程序的结构性和可维护性。

包的导入语句也分为import和from...import...两种,但是无论哪种,在导入时都必须遵循一个原则:凡是导入时带点的,点的左边必须是一个包,否则非法。导入成功后,无此限制。

import包,产生的名称空间的名字来源于原文件,即包下的__init__.py文件,导入包本质就是导入改文件。

2.包的使用

单独导入包名时不会导入包中所有子模块,需要在包下的__init__.py中添加from . import 模块,并且from后import导入的模块,不能带点,否则会有语法错误。f

from aa.bb import * 导入的是bb包中__init__.py文件中的名字,并非bb文件夹下的模块名字。

绝对导入是以包的根路径作为起始位置,相对导入是使用.或者..的方式作为起始。

包以及包中包含的模块都是用于被导入的,不是被直接执行的。环境变量以执行文件为准。比如两个模块均在同一目录下,被其他路径的文件导入,那么这两个模块之间若要导入时,不可直接import,需要添加操作执行文件的路径来导入。

三、日志模块

1.日志级别

日志分为五个级别:CRITICAL、ERROR、WARNING、INFO、DEBUG,依次可以使用数字50、40、30、20、10代替,NOSET表示不设置级别,用0代替。当日志设置为某一级别后,只会记录比该级别更高级别的日志。

#默认界别为warning,输出就只输出warning、error、critical级别日志
import logging
logging.debug("debug_test")
logging.info("info_test")
logging.warning("warning_test")
logging.error("error_test")
logging.critical("critical_test")

2.logging模块的Formatter,Handler,Logger,Filter对象

产生日志对象logger,过滤日志对象Filter,接收日志并控制输出位置的对象Handler,日志格式对象Formatter。

 1 import logging
 2 #1.Logger,产生日志
 3 logger = logging.getLogger("访问日志")
 4 #2.Filter,几乎用不上
 5 #3.Handler,接收logger传来的日志,格式化,并打印到终端或文件
 6 sh = logging.StreamHandler()
 7 fh1 = logging.FileHandler("f1.log",encoding="utf-8")
 8 fh2 = logging.FileHandler("f2.log",encoding="utf-8")
 9 #4.Formatter,日志格式化
10 formatter1 = logging.Formatter(
11     fmt = ‘%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s‘,
12     datefmt=‘%Y-%m-%d %H-%M-%S %p‘,
13 )
14 formatter2 = logging.Formatter(
15     fmt = ‘%(asctime)s : %(message)s‘,
16     datefmt=‘%Y-%m-%d %H-%M-%S %p‘,
17 )
18 formatter3 = logging.Formatter(
19     fmt=‘%(asctime)s : %(module)s : %(message)s‘,
20     datefmt=‘%Y-%m-%d %H-%M-%S %p‘,
21 )
22 #5.为handler绑定日志格式
23 sh.setFormatter(formatter1)
24 fh1.setFormatter(formatter2)
25 fh2.setFormatter(formatter3)
26 #6.为logger绑定handler
27 logger.addHandler(sh)
28 logger.addHandler(fh1)
29 logger.addHandler(fh2)
30 #7.设置日志级别:logger对象的日志级别应该小于或等于handler的日志级别,否则低级别日志无法到到handler
31 logger.setLevel(10)
32 sh.setLevel(10)
33 fh1.setLevel(10)
34 fh2.setLevel(10)
35 #8.测试
36 logger.debug("debug test")
37 logger.info(‘info test‘)
38 logger.warning(‘warning test‘)
39 logger.error(‘error test‘)
40 logger.critical(‘critical test‘)

logging详细用法

在实际编程中使用以上方法较麻烦,可以将日志相关对象创建写在一个py文件中作为模块来调用。

 1 import os
 2 import logging.config
 3 BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #获取上一级目录绝对路径
 4 LOG_PATH=os.path.join(BASE_DIR,‘log‘,‘access.log‘)
 5 COLLECT_PATH=os.path.join(BASE_DIR,‘log‘,‘collect.log‘)
 6 DB_PATH=os.path.join(BASE_DIR,‘db‘,‘user‘)
 7
 8 # 定义三种日志输出格式 开始
 9 standard_format = ‘[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]‘ 10                   ‘[%(levelname)s][%(message)s]‘
11
12 simple_format = ‘[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s‘
13
14 id_simple_format = ‘[%(levelname)s][%(asctime)s] %(message)s‘
15
16 # log配置字典
17 LOGGING_DIC = {
18     ‘version‘: 1,
19     ‘disable_existing_loggers‘: False,
20     ‘formatters‘: {
21         ‘standard‘: {
22             ‘format‘: standard_format
23         },
24         ‘simple‘: {
25             ‘format‘: simple_format
26         },
27         ‘id_simple‘ : {
28             ‘format‘ : id_simple_format
29         },
30     },
31     ‘filters‘: {},
32     ‘handlers‘: {
33         #打印到终端的日志
34         ‘console‘: {
35             ‘level‘: ‘DEBUG‘,
36             ‘class‘: ‘logging.StreamHandler‘,  # 打印到屏幕
37             ‘formatter‘: ‘simple‘
38         },
39         #打印到文件的日志,收集info及以上的日志
40         ‘default‘: {
41             ‘level‘: ‘DEBUG‘,
42             ‘class‘: ‘logging.handlers.RotatingFileHandler‘,  # 保存到文件
43             ‘formatter‘: ‘standard‘,
44             ‘filename‘: LOG_PATH,  # 日志文件
45             ‘maxBytes‘: 1024*1024*5,  # 日志大小 5M
46             ‘backupCount‘: 5,
47             ‘encoding‘: ‘utf-8‘,  # 日志文件的编码,再也不用担心中文log乱码了
48         },
49         ‘collect‘: {
50             ‘level‘: ‘DEBUG‘,
51             ‘class‘: ‘logging.handlers.RotatingFileHandler‘,  # 保存到文件
52             ‘formatter‘: ‘simple‘,
53             ‘filename‘: COLLECT_PATH,  # 日志文件
54             ‘maxBytes‘: 1024*1024*5,  # 日志大小 5M
55             ‘backupCount‘: 5,
56             ‘encoding‘: ‘utf-8‘,  # 日志文件的编码,再也不用担心中文log乱码了
57         },
58     },
59     ‘loggers‘: {
60         ‘‘: {
61             ‘handlers‘: [‘default‘, ‘console‘,‘collect‘],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
62             ‘level‘: ‘DEBUG‘,
63             ‘propagate‘: False,  # 向上(更高level的logger)传递
64         },
65     },
66 }

logging配置文件

loggers的子字典中key表示logger名,若将key设置为空key,这样在生成logger对象时,使用logging.getLogger(__name__),不同文件会产生相应的logger名,可以使得日志输出时标识不同。

‘loggers‘: {
        ‘‘: {
            ‘handlers‘: [‘default‘, ‘console‘],
            ‘level‘: ‘DEBUG‘,
            ‘propagate‘: True,
        },
}

导入logging的配置文件后,定义log对象生成的函数。

from conf import settings
import logging.config

def logger_handle(log_name):
    logging.config.dictConfig(settings.LOGGING_DIC)
    logger = logging.getLogger(log_name)
    return logger

在需要记录log的文件中导入上述文件。

from lib import common
def test():
    print("支付成功")
    log_msg = "xxx在商城消费8元"
    logger = common.logger_handle("支付日志")
    logger.info(log_msg)

四、re模块

正则是用来描述一类实物的规则,主要用于匹配字符串。

import re
#\w和\W
print(re.findall(‘\w‘,"asdf 1234 %@^#"))
print(re.findall(‘\W‘,"asdf 1234 %@^#"))
#\s和\S,\n和\t都可被\s匹配
print(re.findall(‘\s‘,"asdf 1234 %@^#"))
print(re.findall(‘\S‘,"asdf 1234 %@^#"))
print(re.findall(‘\s‘,"asdf 1234\n\t %@^#"))
#\d和\D
print(re.findall(‘\d‘,"asdf 1234 %@^#"))
print(re.findall(‘\D‘,"asdf 1234 %@^#"))
#^和$
print(re.findall(‘^a‘,"asdf 1234 %@^#"))
print(re.findall(‘#$‘,"asdf 1234 %@^#"))
#匹配重复
print(re.findall(‘a.d‘,"asdf 1234 %@^#"))
print(re.findall(‘as*‘,"asdf ass 1234 %@^#"))
print(re.findall(‘as?‘,"asdf ass 1234 %@^#"))
print(re.findall(‘a.*‘,"asdf ass 1234 %@^#"))
print(re.findall(‘a.*?‘,"asdf ass 1234 %@^#")) #.*默认贪婪匹配,.*?为非贪婪匹配
print(re.findall(‘as+‘,"asdf ass 1234 %@^#"))
print(re.findall(‘as{0,2}‘,"asdf ass 1234 %@^#"))
print(re.findall(‘a[cs%]d‘,"asdf acd 1234  a%[email protected]^#")) #[]内都为普通字符,如果-没有转义,需要放到[]的首尾处
#分组
print(re.findall(‘a(\w+)‘,"asdf ass 1234 %@^#")) #只输出括号中的
print(re.findall(‘a(?:\w+)‘,"asdf ass 1234 %@^#")) #输出匹配到的全部内容

re模块相关的方法

findall返回所有满足条件的结果,放在列表中

import re
print(re.findall(‘\d\s‘,"asdf a2 1234 %@^#"))

search只找到第一个匹配然后返回包含匹配结果的对象,通过group()来获取匹配的字符串,如果没有匹配到内容,返回None

import re
print(re.search(‘\d\s‘,"asdf a2 1234 %@^#").group())

match同search,只不过是从字符串开始匹配

import re
print(re.search(‘^a‘,"asdf a2 1234 %@^#").group())

split按照匹配到的字符进行字符串分割。

import re
print(re.split(‘[ab]‘,‘abcd‘))#从开头按照a分割为‘‘和‘bcd‘,在按照b分割为‘‘和‘cd‘

sub,将字符串中匹配的到子串替换为新的字符串

import re
print(re.sub(‘a‘,‘A‘,‘aabbccad‘)) #不指定n,默认替换所有
print(re.sub(‘a‘,‘A‘,‘aabbccad‘,1)) #只替换第一个
print(re.sub(‘^(\w)(.*?)(\w)$‘,r‘\3\2\1‘,‘aabbccad‘,1)) #加括号后自动编序号,按照序号交换收尾字符

compile,用正则表达式生成一个对象,每次使用时通过对象调用相关方法

import re
obj=re.compile("(?:\d{0,3}\.){3}\d{0,3}")
print(obj.findall("ipaddr:10.1.1.1\n"))
print(obj.findall("src_ip:192.168.1.1"))

五、time和datetime模块

python中的几个时间:

  a) 时间戳,表示从1970年1月1日00:00:00开始按照秒计算的偏移量。可使用time.time查看当前时间戳。

  b)格式化的时间字符串

  c)结构化的时间:struct_time元组工9个元素,分别是年、月、日

import time
print(time.time())  #时间戳
print(time.strftime("%Y-%m-%d %X")) #格式化时间
print(time.localtime()) #本地时区结构化时间
print(time.gmtime())   #UTC时区结构化时间

%a    Locale’s abbreviated weekday name.
%A    Locale’s full weekday name.
%b    Locale’s abbreviated month name.
%B    Locale’s full month name.
%c    Locale’s appropriate date and time representation.
%d    Day of the month as a decimal number [01,31].
%H    Hour (24-hour clock) as a decimal number [00,23].
%I    Hour (12-hour clock) as a decimal number [01,12].
%j    Day of the year as a decimal number [001,366].
%m    Month as a decimal number [01,12].
%M    Minute as a decimal number [00,59].
%p    Locale’s equivalent of either AM or PM.    (1)
%S    Second as a decimal number [00,61].    (2)
%U    Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0.    (3)
%w    Weekday as a decimal number [0(Sunday),6].
%W    Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0.    (3)
%x    Locale’s appropriate date representation.
%X    Locale’s appropriate time representation.
%y    Year without century as a decimal number [00,99].
%Y    Year with century as a decimal number.
%z    Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59].
%Z    Time zone name (no characters if no time zone exists).
%%    A literal ‘%‘ character.

格式化字符串的时间格式

格式化时间字段含义

三种时间直接转换关关系

import time
print(time.localtime())  #获取本地时间
print(time.localtime(13333333))  #时间戳转换为机构化时间
print(time.mktime(time.localtime()))  #结构化时间转换为时间戳
print(time.strftime("%Y-%m-%d %X",time.localtime())) #结构化时间转换为格式化时间
print(time.strptime("2018-01-09 21:15:00","%Y-%m-%d %X")) #格式化时间转换为结构化时间

原文地址:https://www.cnblogs.com/n1ghtwatcher/p/8215087.html

时间: 2024-12-29 23:12:24

Python学习笔记五(模块与包)的相关文章

python学习笔记(五) - 模块

一. 使用模块 引入sys模块,使用import #!/usr/bin/env python # -*- 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: p

python学习笔记(模块、包、标准库)

模块 前面有简单介绍如何使用import从外部模块获取函数并且为自己的程序所用: >>> import math>>> math.sin(0)0.0>>> 模块是程序 任何python程序都可以作为模块导入.假设写如下程序,并且将它保存为以F:\python\myDemo\hello.py print 'hello,world' 下面通过python解释器调用: >>> import sys>>> sys.path.

Python学习笔记—itertools模块

这篇是看wklken的<Python进阶-Itertools模块小结> 学习itertools模块的学习笔记 在看itertools中各函数的源代码时,刚开始还比较轻松,但后面看起来就比较费劲... 1.itertools.count(start=0,step=1) 此函数用来创建一个迭代器,生成从n开始的连续整数,如果忽略n,则从0开始计算 如果超出了sys.maxint,计数器将溢出并继续行-sys.maxint-1开始计算 定义: def count(start=0, step=1):

python学习笔记(八)-模块

大型python程序以模块和包的形式组织.python标准库中包含大量的模块.一个python文件就是一个模块.1.标准模块 python自带的,不需要你安装的2.第三方模块 需要安装,别人提供的. pip install xxx 自动化安装的 手动安装 首先下载安装包 解压 在命令行里面进入到这个解压之后的目录 执行python setup.py install3.自己写的 自己写的python文件import xx 导入一个文件 ,导入文件的实质是什么,把这个python运行一次import

Python学习笔记-常用模块

1.python模块 如果你退出 Python 解释器并重新进入,你做的任何定义(变量和方法)都会丢失.因此,如果你想要编写一些更大的程序,为准备解释器输入使用一个文本编辑器会更好,并以那个文件替代作为输入执行.这就是传说中的 脚本.随着你的程序变得越来越长,你可能想要将它分割成几个更易于维护的文件.你也可能想在不同的程序中使用顺手的函数,而不是把代码在它们之间中拷来拷去. 为了满足这些需要,Python 提供了一个方法可以从文件中获取定义,在脚本或者解释器的一个交互式实例中使用.这样的文件被称

Python学习笔记2—模块

模块的使用 引用模块的两种形式 形式一: import module_name 形式二: from module1 import module11   (module11是module的子模块) 例:引用精确除法模块 >>> 5/2 2 >>> from __future__ import division >>> 5/2 2.5 >>> 5//2 2 >>> 如过需要进行开方,乘方,对数等运算就需要用到Python

python学习笔记五:模块和包

一.模块用import导入 cal.py: #!/usr/bin/python def add(x,y): return x+y if __name__ == '__main__': print add(1,2) 注:__name__为内置变量,如果直接在CLI中调用值为__mail__,否则为文件名. 在new.py中导入: import cal print cal.add(2,3); 二.包:按目录名组织的模块 1.建立一个名字为包名字的文件夹 2.在该文件夹下创建一个__init__.py

python学习笔记(五):装饰器、生成器、内置函数、json

这周学习了装饰器和生成器,写下博客,记录一下装饰器和生成器相关的内容. 一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里面每个函数都加一个功能,用来统计每个函数的运行时间是多少,找出来运行比较慢的函数,来优化代码,就需要添加一个新的功能,来统计程序的运行时间,那这样的话,就得修改每个函数了,需要改代码,但是代码特别多,改完了公司倒闭了,这时候装饰

python学习笔记glob模块

python有许多的类库,现将学习记录下来,以供以后回顾复习: 1.glob模块 用于文件名操作,匹配指定目录下的文件,常用的有两个函数: glob(pattern),返回匹配的文件的列表. iglob(pattern),返回生成器,可以遍历匹配的文件. 示例代码: glob()bogon:datasets xuguoqiang$ ls matrixA.txt matrixB.txt test words.txt files = glob.glob('*.txt') >>> for fi