美文网首页PythonPythoner集中营零基础学Phyton
head first python(第二章)–学习笔记

head first python(第二章)–学习笔记

作者: dnaEMx | 来源:发表于2015-04-13 21:38 被阅读552次

    head first python(第二章)--学习流程图


    1.函数转换为模块

    函数转换为模块后,就可以灵活的使用模块,方便代码分类,避免代码堆积在一个文件上。当你写的python代码达到一定数量并且功能开始丰富的时候,就必须要这么做了。而模块会存在python本地副本目录里面,所以需要打包,需要安装模块到副本目录,以便python解释器能够找到模块,然后使用。

    python搜索模块的目录位置:(大致需要知道就行了)

    python

    Python 2.6.6 (r266:84292, Jan 22 2014, 09:37:14) 
    [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import sys
    >>> sys.path
    ['', '/usr/lib/python26.zip', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old', '/usr/lib/python2.6/lib-dynload', '/usr/lib/python2.6/site-packages']
    >>> 
    

    1.1 创建目录和文件

    创建目录nester

    mkdir nester
    

    进入nester目录并创建nester.py 和setup.py

    cd netster

    vi nester.py

    """This is the "nester.py" module and it provides one function called print_lol() 
        which prints lists that may or may not include nested lists."""
    
    def print_lol(the_list):
        """This function takes one positional argument called "the_list", which 
            is any Python list (of - possibly - nested lists). Each data item in the 
            provided list is (recursively) printed to the screen on it’s own line."""
    
    for each_item in the_list:
        if isinstance(each_item, list):
            print_lol(each_item)
        else:
            print(each_item)
    

    nester.py代码模块文件,格式要严谨,不必加上其他的东西。

    vi setup.py

    from distutils.core import setup
    
    setup( 
        name         = 'nester', 
        version      = '1.0.0', 
        ## TODO: be sure to change these next few lines to match your details!
        py_modules   = ['nester'],
        author       = 'hfpython',
        author_email = 'hfpython@headfirstlabs.com',
        url          = 'http://www.headfirstlabs.com',
        description  = 'A simple printer of nested lists',
     )
    

    setup.py是模块发布的元文件metafile,里面包含模块的一些发布信息。按照格式和要求编写即可。

    1.2 使用python setup.py sdist命令打包代码,生成发布包

    python setup.py sdist
    running sdist
    warning: sdist: manifest template 'MANIFEST.in' does not exist (using default file list)
    warning: sdist: standard file not found: should have one of README, README.txt
    writing manifest file 'MANIFEST'
    creating nester-1.0.0
    making hard links in nester-1.0.0...
    hard linking nester.py -> nester-1.0.0
    hard linking setup.py -> nester-1.0.0
    creating dist
    tar -cf dist/nester-1.0.0.tar nester-1.0.0
    gzip -f9 dist/nester-1.0.0.tar
    tar -cf dist/nester-1.0.0.tar nester-1.0.0
    gzip -f9 dist/nester-1.0.0.tar
    removing 'nester-1.0.0' (and everything under it)
    

    打包后会生成目录dist和文件MANIFEST

    ├── dist
    │   └── nester-1.0.0.tar.gz
    ├── MANIFEST
    ├── nester.py
    └── setup.py
    

    cat MANIFEST

    nester.py
    setup.py
    

    发布后会多了dist目录和MANIFEST文件,这2个是发布的生成的包和相关配置文件。

    1.3 安装打包代码,即使安装nester模块

    python setup.py install

    running install
    running build
    running build_py
    copying nester.py -> build/lib
    running install_lib
    copying build/lib/nester.py -> /usr/lib/python2.6/site-packages
    byte-compiling /usr/lib/python2.6/site-packages/nester.py to nester.pyc
    running install_egg_info
    Removing /usr/lib/python2.6/site-packages/nester-1.0.0-py2.6.egg-info
    Writing /usr/lib/python2.6/site-packages/nester-1.0.0-py2.6.egg-info
    

    安装后

    .
    ├── build
    │   └── lib
    │   └── nester.py
    ├── dist
    │   └── nester-1.0.0.tar.gz
    ├── MANIFEST
    ├── nester.py
    └── setup.py
    

    安装后悔出现build目录,这个就是用发布包解压出来的库和模块代码,会统一放到python的模块搜索目录里面去。

    1.4 模块使用的时候就是import nester

    不过出现了错误

    >>> import nester
    >>> print_lol(a)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'print_lol' is not defined
    >>> 
    

    是因为命名空间的关系,主python程序中(以及idle shell中)的代码与一个名为main的命名空间关联。所以的话不能直接使用print_lol,而要加上命名空间nester.print_lol()

    知识点:

    1.命名空间是为了让python解释器就会知道去哪里找这个函数,命名空间格式:首先是模块名字,然后是一个点号,再后面是函数名。
    
    2.如果使用from nester import print_lol,就会把指定的函数print_lol增加到当前命名空间中,这样就不用加上命名空间来调用函数了。
    

    2.用额外的参数控制行为(需要对嵌套列表进行缩进)

    这样可以增加功能而不用增加多余函数代码(print_lol2)。

    写新代码之前先考虑BIF(内置函数)

    rang() 返回一个迭代器,根据需要生成一个指定范围的数字。

    根据需求写了这样的代码,但运行报错
    增加了一个level参数,默认等于0,遇到嵌套列表就是用rang(level)来进行缩进

    def print_lol(a_list, level=0):
        """Prints each item in a list, recursively descending
        into nested lists (if necessary)."""
    
    for each_item in a_list:
        if isinstance(each_item, list):
            print_lol(each_item, level)
        else:
            for l in range(level):
                print("\t", end='')
            print(each_item)
    

    出现错误了:TypeError:print_lol() take exactly 2 positional arguments (1 given)

    原因是print_lol需要2个参数,目前只有一个。

    要改成

    def print_lol(a_list, level=0):
        """Prints each item in a list, recursively descending
        into nested lists (if necessary)."""
    
    for each_item in a_list:
        if isinstance(each_item, list):
            print_lol(each_item, level+1)  #因为不加1的话函数调用还是会出现level=0,就没有意义了
        else:
            for l in range(level):
                print("\t", end='')
            print(each_item)
    

    然后更新代码发布包

    from distutils.core import setup
    
    setup( 
        name         = 'nester', 
        version      = '1.1.0',     #这里改成1.1.0了,更新了新代码版本
        ## TODO: be sure to change these next few lines to match your details!
        py_modules   = ['nester'],
        author       = 'hfpython',
        author_email = 'hfpython@headfirstlabs.com',
        url          = 'http://www.headfirstlabs.com',
        description  = 'A simple printer of nested lists',
     )
    

    3.改变了API

    因为增加了level参数,改变了默认的行为(最原始的默认行为不想要缩进),导致打印出来的格式有异常,需要再增加一个可选参数,来控制缩进功能的使用。

    增加一个indent参数来控制缩进是否打开

    def print_lol(a_list, indent=False, level=0):
        """Prints each item in a list, recursively descending
        into nested lists (if necessary)."""
    
    for each_item in a_list:
        if isinstance(each_item, list):
            print_lol(each_item, indent, level+1)
        else:
            if indent:
                for l in range(level):
                    print("\t", end='')
            print(each_item)
    

    需要注意的是所有代码如果不是idel中运行的话,都需要加上#!/usr/bin/python在顶部。


    原文链接:http://www.godblessyuan.com/2015/04/13/head_first_python_chapter_2_learning/

    相关文章

      网友评论

        本文标题:head first python(第二章)–学习笔记

        本文链接:https://www.haomeiwen.com/subject/oxwkfttx.html