zoukankan      html  css  js  c++  java
  • Python之模块和包(Day21)

    一.Python模块

    Python模块(module),是一个Python文件,以.py结尾,包含了Python对象定义和Python语句.

      模块让你能够有逻辑的组织你的Python代码段

      把相关的代码分配到一个模块里能让你的代码更好用,更易懂

      模块能定义函数,类和变量,模块里也能包含可执行代码

    1.1 import语句

    一个模块只会被导入一次,不管你执行多少次import。这样可以防止导入模块被一遍又一遍的执行

    #demo.py
    import my_moudle #只在第一次导入时才执行my_moudle.py内代码,此处的显式效果是只打印一次'from the my_moudle.py'
                ,当然其他的顶级代码也都被执行了,只不过没有显示效果.
    import my_moudle import my_moudle import my_moudle ''' 执行结果: from the my_moudle.py ''' demo.py

    1.2 首次导入模块my_moudle时会做三件事

      1.为源文件(my_moudle)创建新的名称空间,在my_moudle中定义的函数和方法若是使用了global访问的就是这个名称空间

      2.在新创建的命名空间执行模块中包含的代码,见初始导入import my_moudle

    1.3 from....import语句

    Python的from语句让你从模块中导入一个指定的部分到当前命名空间中,语法如下:

    from modname import name1[, name2[, ... nameN]]

    例如,要导入模块 fib 的 fibonacci 函数,使用如下语句:

    from fib import fibonacci

    这个声明不会吧整个fib模块导入到当前命名空间中,它只会将fib里的fibonacci 单个引入到执行这个声明的模块的全局符号表

    1.4 from......import*  语句

    把一个模块的所有内容全部导入到当前的命名空间也是可行的,值需要使用如下声明:

    from modname import *

    这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多的使用。

    例如我们想一次性的引入math模块中的所有东西,语句如下:

    from math import *

    1.5 dir() 函数

    dir() 函数一个排好序的字符串列表,内容是一个模块定义过的名字。

    返回列表容纳在一个模块里定义的所有模块,变量和函数。eg:

    # 导入内置math模块
    import math
     
    content = dir(math)
     
    print content;

    以上实例输出结果:

    ['__doc__', '__file__', '__name__', 'acos', 'asin', 'atan', 
    'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 
    'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log',
    'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 
    'sqrt', 'tan', 'tanh']

    在这里,特殊字符串变量_name_ 指向模块的名字,_file_指向该模块导入的文件名

    二.Python中的  包

    包是一个分层次的文件目录结构,他定义了一个模块及子包,和子包下的子包等组成的Python的应用环境

    简单来说,包就是文件夹,但是该文件夹下必须存在_init_.py文件,该文件的内容可以为空,_init_.py用于标识当前文件夹是一个包

    注意:

      1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

      2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块

     2.1  from....import...

    需要注意的是from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误

    如:from a import b.c 是语法错误

    我们在与包glance同级别的文件测试

    1 from glance.db import models
    2 models.register_models('mysql')
    3 
    4 from glance.db.models import register_models
    5 register_models('mysql')

    2.2 绝对导入和相对导入

    绝对导入:以glance作为起始

    相对导入:用.....或者.....的方法作为起始(只能在一个包中使用,不能用在不同的目录内)

    例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py

    在glance/api/version.py
    
    #绝对导入
    from glance.cmd import manage
    manage.main()
    
    #相对导入
    from ..cmd import manage
    manage.main()

    测试结果:注意一定要在于glance同级的文件中测试

    1 from glance.api import versions 

    2.3 软件开发规范

    #=============>bin目录:存放执行脚本
    #start.py
    import sys,os
    
    BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(BASE_DIR)
    
    from core import core
    from conf import my_log_settings
    
    if __name__ == '__main__':
        my_log_settings.load_my_logging_cfg()
        core.run()
    
    #=============>conf目录:存放配置文件
    #config.ini
    [DEFAULT]
    user_timeout = 1000
    
    [egon]
    password = 123
    money = 10000000
    
    [alex]
    password = alex3714
    money=10000000000
    
    [yuanhao]
    password = ysb123
    money=10
    
    #settings.py
    import os
    config_path=r'%s\%s' %(os.path.dirname(os.path.abspath(__file__)),'config.ini')
    user_timeout=10
    user_db_path=r'%s\%s' %(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
                         'db')
    
    
    #my_log_settings.py
    """
    logging配置
    """
    
    import os
    import logging.config
    
    # 定义三种日志输出格式 开始
    
    standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' 
                      '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字
    
    simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
    
    id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
    
    # 定义日志输出格式 结束
    
    logfile_dir = r'%slog' %os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # log文件的目录
    
    logfile_name = 'all2.log'  # log文件名
    
    # 如果不存在定义的日志目录就创建一个
    if not os.path.isdir(logfile_dir):
        os.mkdir(logfile_dir)
    
    # log文件的全路径
    logfile_path = os.path.join(logfile_dir, logfile_name)
    
    # log配置字典
    LOGGING_DIC = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': standard_format
            },
            'simple': {
                'format': simple_format
            },
        },
        'filters': {},
        'handlers': {
            #打印到终端的日志
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',  # 打印到屏幕
                'formatter': 'simple'
            },
            #打印到文件的日志,收集info及以上的日志
            'default': {
                'level': 'DEBUG',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                'formatter': 'standard',
                'filename': logfile_path,  # 日志文件
                'maxBytes': 1024*1024*5,  # 日志大小 5M
                'backupCount': 5,
                'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
            },
        },
        'loggers': {
            #logging.getLogger(__name__)拿到的logger配置
            '': {
                'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',
                'propagate': True,  # 向上(更高level的logger)传递
            },
        },
    }
    
    
    def load_my_logging_cfg():
        logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
        logger = logging.getLogger(__name__)  # 生成一个log实例
        logger.info('It works!')  # 记录该文件的运行状态
    
    if __name__ == '__main__':
        load_my_logging_cfg()
    
    #=============>core目录:存放核心逻辑
    #core.py
    import logging
    import time
    from conf import settings
    from lib import read_ini
    
    config=read_ini.read(settings.config_path)
    logger=logging.getLogger(__name__)
    
    current_user={'user':None,'login_time':None,'timeout':int(settings.user_timeout)}
    def auth(func):
        def wrapper(*args,**kwargs):
            if current_user['user']:
                interval=time.time()-current_user['login_time']
                if interval < current_user['timeout']:
                    return func(*args,**kwargs)
            name = input('name>>: ')
            password = input('password>>: ')
            if config.has_section(name):
                if password == config.get(name,'password'):
                    logger.info('登录成功')
                    current_user['user']=name
                    current_user['login_time']=time.time()
                    return func(*args,**kwargs)
            else:
                logger.error('用户名不存在')
    
        return wrapper
    
    @auth
    def buy():
        print('buy...')
    
    @auth
    def run():
    
        print('''
    购物
    查看余额
    转账
        ''')
        while True:
            choice = input('>>: ').strip()
            if not choice:continue
            if choice == '1':
                buy()
    
    
    
    if __name__ == '__main__':
        run()
    
    #=============>db目录:存放数据库文件
    #alex_json
    #egon_json
    
    #=============>lib目录:存放自定义的模块与包
    #read_ini.py
    import configparser
    def read(config_file):
        config=configparser.ConfigParser()
        config.read(config_file)
        return config
    
    #=============>log目录:存放日志
    #all2.log
    [2017-07-29 00:31:40,272][MainThread:11692][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
    [2017-07-29 00:31:41,789][MainThread:11692][task_id:core.core][core.py:25][ERROR][用户名不存在]
    [2017-07-29 00:31:46,394][MainThread:12348][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
    [2017-07-29 00:31:47,629][MainThread:12348][task_id:core.core][core.py:25][ERROR][用户名不存在]
    [2017-07-29 00:31:57,912][MainThread:10528][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
    [2017-07-29 00:32:03,340][MainThread:12744][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
    [2017-07-29 00:32:05,065][MainThread:12916][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
    [2017-07-29 00:32:08,181][MainThread:12916][task_id:core.core][core.py:25][ERROR][用户名不存在]
    [2017-07-29 00:32:13,638][MainThread:7220][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
    [2017-07-29 00:32:23,005][MainThread:7220][task_id:core.core][core.py:20][INFO][登录成功]
    [2017-07-29 00:32:40,941][MainThread:7220][task_id:core.core][core.py:20][INFO][登录成功]
    [2017-07-29 00:32:47,222][MainThread:7220][task_id:core.core][core.py:20][INFO][登录成功]
    [2017-07-29 00:32:51,949][MainThread:7220][task_id:core.core][core.py:25][ERROR][用户名不存在]
    [2017-07-29 00:33:00,213][MainThread:7220][task_id:core.core][core.py:20][INFO][登录成功]
    [2017-07-29 00:33:50,118][MainThread:8500][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
    [2017-07-29 00:33:55,845][MainThread:8500][task_id:core.core][core.py:20][INFO][登录成功]
    [2017-07-29 00:34:06,837][MainThread:8500][task_id:core.core][core.py:25][ERROR][用户名不存在]
    [2017-07-29 00:34:09,405][MainThread:8500][task_id:core.core][core.py:25][ERROR][用户名不存在]
    [2017-07-29 00:34:10,645][MainThread:8500][task_id:core.core][core.py:25][ERROR][用户名不存在]
    示例规范
    有一种能力,是持续不断的努力
  • 相关阅读:
    进程&线程
    PLAN
    Note-Virus
    编译器 CL.EXE / RC.EXE
    windows API
    centos6.5系统中yum命令出错
    VMware Workstation10 下安装 CentOS6.5( 安装图文教程 )
    Linux下网络能ping通地址 但是ping不通域名
    MySQL数据库优化的八种方式(经典必看)
    Java中常见的对象类型简述(DO、BO、DTO、VO、AO、PO)
  • 原文地址:https://www.cnblogs.com/shaojiafeng/p/7326150.html
Copyright © 2011-2022 走看看