zoukankan      html  css  js  c++  java
  • Python基础(8)

    Python

    模块的物理形式就是文件;一个文件对应一个模块。文件名就是模块名+.py

    模块定义了自己独有的命名空间。在其定义的属性,函数,类都隶属于该空间。

    通过import关键字我们可以导入模块:

    import  module1,[module2,[…moduleN]]

    也可以使用多行导入的方式:

    import module1[

           :

    Import moduleN]

    两种方式在性能上没有差别,但是多行导入从可读性上来讲更加清晰

    推荐的import语句导入模块顺序:

    python标准库àpython第三方库à应用程序自定义模块

    如果解释器执行到import语句,如果在搜索路径中找到了指定的模块,就会加载它。

    一个模块在第一次导入时加载并执行(顶层代码),后续再被导入时不会再执行。

    如果在一个模块的顶层导入的模块,该模块具有Global的作用域,如果我们是在函数内部导入的,则具有Local的作用域。

    导入的模块必须在搜索的路径中,如果没有则会抛出找不到该模块的异常。搜索路径为sys模块中的path属性。该path属性是一个列表。如果我们的模块路径不在该列表中,我们要加入到该列表。

    >>> import sys
    >>> sys.path
    ['', 'C:\Windows\system32\python27.zip', 'C:\Python27\DLLs', 'C:\Python27\lib', 'C:\Python27\lib\plat-win', 'C:\Python27\lib\lib-tk', 'C:\Python27', 'C:\Python27\lib\site-packages', 'C:\Py
    thon27\lib\site-packages\win32', 'C:\Python27\lib\site-packages\win32\lib', 'C:\Python27\lib\site-packages\Pythonwin', 'C:\Python27\lib\site-packages\wx-2.8-msw-ansi']
    >>>
    >>> sys.path.append('C:\Windows')
    >>> sys.path
    ['', 'C:\Windows\system32\python27.zip', 'C:\Python27\DLLs', 'C:\Python27\lib', 'C:\Python27\lib\plat-win', 'C:\Python27\lib\lib-tk', 'C:\Python27', 'C:\Python27\lib\site-packages', 'C:\Py
    thon27\lib\site-packages\win32', 'C:\Python27\lib\site-packages\win32\lib', 'C:\Python27\lib\site-packages\Pythonwin', 'C:\Python27\lib\site-packages\wx-2.8-msw-ansi', 'C:\Windows']
    >>>

    from module import name1,[name2,[…nameN]]

    通过上述语句可以导入一个模块的属性,把其引入到当前的命名空间中。

    这样我们在使用这些属性时就不需要再加入模块名了。如果想导入该模块的所有属性。则使用如下语句:

    from module import *

    但对于上面的语句我们不建议使用,因为它污染了当前的命名空间,很可能会覆盖当前命名空间中已有的名称

    更标准的多行导入语句格式如下:

    from module import (name1,name2...nameN)

    扩展的import语句:as,可以解决导入的模块或模块属性命名冲突的问题,或者名称太长的问题

    import module as …

    from module import name as …

    globals()和locals():分别返回调用者全局和局部命名空间的字典。在全局命名空间下,两者返回相同的字典,因为这是的局部命名空间就是全局空间。

    包:

    包是一个有层次的文件目录结构,它定义了一个由模块和子包组成的python应用程序执行环境,主要用于解决以下问题:

    l为平坦的命名空间加入有层次的组织结构
    l允许程序员把有联系的模块组合到一起
    l允许分发者使用目录结构而不是一大堆混乱的文件
    l帮助解决有冲突的模块名称

    包也使用句点属性标识来访问它们的元素,使用标准的import和from-import语句导入包中的模块。

    每个包目录下都必须有一个__init__.py文件,在导入包时被执行。它控制着包的导入行为,可以是空文件,此时仅仅导入包而不做任何其他事情。但如果需要预导入一些模块,就需要在__init__.py中编码实现。

    使用from … import *的方式导入包时,在__init__.py中可以通过__all__指定本包中哪

    些模块需要被导入

    举例: 
    Sound/__init__.py是一个空文件, 则:

    >>> from Sound import * 
    >>> dir()  
     ['__builtins__', '__doc__', '__name__', '__package__', 'pywin', 'sys']

    在Sound/__init__.py中, 写一行:

    __all__ = ['Effects', 'Filters']

    则:

    >>> from Sound import * 

    >>> dir() 

    ['Effects', 'Filters', '__builtins__', '__doc__', '__name__', '__package__', 'pywin', 'sys']

    警惕导入循环:

    a.py代码:

    from b import impModule

    b.py代码:

    import a

    def impModule():

        print "iimpModule() called”   

    impModule()

    b.py代码修改后:

    def impModule():

        import a

        print "iimpModule() called”   

    impModule()

    作用域

    Python使用名称空间的概念存储对象,这个名称空间就是对象作用的区域,不同对象存在于不同的作用域。下面是不同对象的作用域规则:

    p  每个模块就是一个全局作用域。
    p  每次调用一个函数就创建一个局部作用域。
    p  函数内的赋值对象属局部作用域,除非使用global关键字进行声明
     

    名字解析的规则。

    LGB (Local  Global  Built-in)

    l  大多数名字引用在三个作用域中查找:先局部(Local),次之全局(Global),再次之内置(Built-in)。
    l  如想在局部作用域中改变全局作用域的对象,必须使用global关键字。'global'声明把赋值的名字映射到一个包含它的模块的作用域中。
     

    单个模块中的全局变量与局部变量:

    >>> g = 123
    >>> def func():
    ...     g = 'a'
    ...     return g
    ...
    >>> func()
    'a'

    func 函数中局部变量g隐藏了全局变量

    >>> g = 123
    >>> def func():
    ...     global g
    ...     g = 4
    ...     print g
    ...
    >>> func()
    4
    >>> print g
    4
    >>>
    >>> g = 123
    >>> def func():
    ...     k = g
    ...     print g,k
    ...     g = 4
    ...
    >>> func()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in func
    UnboundLocalError: local variable 'g' referenced before assignment
    >>>

    Python运行代码时是先编译的。对g 赋值,就成了局部变量。

    跨模块的作用域:

    #imptee.py代码:

    foo = "abc"

    def show():

        print "foo from imptee:%s"%foo

    #impter.py代码:

    from imptee import foo,show

    show()

    foo = 123

    print "foo from impter:%s"%foo

    show()

    猜猜执行impter.py的结果?

    在impter.py中,foo实际上是该模块的局部变量,foo = 123不会改变imptee.py中的foo

    再想一下,如何改变imptee.py中的foo?

    #impter.py代码:

    import imptee

    imptee.show()

    imptee.foo = 123

    print "foo from impter:%s"%imptee.foo

    imptee.show()

  • 相关阅读:
    LCA --算法竞赛专题解析(29)
    倍增与ST算法 --算法竞赛专题解析(28)
    可持久化线段树(主席树) --算法竞赛专题解析(27)
    莫队算法 --算法竞赛专题解析(26)
    分块 --算法竞赛专题解析(25)
    表格标题或内容平铺样式
    SpringMVC传参
    按字节截取字符串
    Redis常用命令及知识
    修改数据库字段类型或名字
  • 原文地址:https://www.cnblogs.com/TonyZhao/p/3530100.html
Copyright © 2011-2022 走看看