模块是很是简单的Python文件,单个Python文件就是一个模块,两个文件就是两个模块。html
import语句是用来导入模块或者从模块里导入特定的类或者函数。如前面咱们用过的math模块,从而可使用sqrt函数来计算距离。python
假若有一个包含Database类的database.py的模块。现有另外一个模块为product.py,它须要从database.py里实例化一个Database类,而后就能够在数据库中执行相关产品查询。程序员
import database db = database.Database() #数据库搜索操做
这时任何在database这个模块里面的类或者函数,均可以经过database.<something>这种激发访问。或者,也能够用from ... import语法来导入一个类。数据库
from database import Database db = Database()
也能够将导入的类进行重命名编程
from database import Database as DB # 重命名 db = DB()
也能够在一行里面导入多项,好比database还含有Query类编程语言
from database import Database, Query
可是,不少教程与经验建议不要导入模块里面全部的类,以下的写法是不采用的。函数
from database import *
一个包(package)就是放在一个文件夹里的模块集合。包的名字就是文件夹的名字。咱们须要作的是告诉python这个文件夹是一个包,并且把一个名为__init__.py的文件(一般是空的)放在这个文件夹里。若是咱们忘记建立这个文件夹,就无法从这个文件夹里面导入那些模块。测试
例如在咱们的工做目录里,把咱们的模块放在了一个叫ecommerce(电子商务)的包里,这个目录一样包含一个main.py的文件用来启动程序。在ecommerce包里再添加一个payments的包用来管理不一样的付款方式,文件夹的层次结构以下所示:spa
parent_directory/
main.py
ecommerce/
__init__.py database.py products.py payments/ __init__.py paypal.py authorizenet.py
其中producs.py的有Product类code
class Product: pass
database.py有Database类
class Database: pass
模块的导入方式有两种:绝对导入和相对导入。
要先给出这个模块、函数的完整路径,如在main.py须要访问produces模块中的Product类,使用使用以下的方法进行绝对导入:
import ecommerce.products product = ecommerce.products.Product()
或者(我的比较喜欢这种方式):
from ecommerce.products import Product product = Product()
或者:
from ecommerce import products product = products.Product()
import语句使用点号做为分隔符来分隔包或者模块。
上述的均可以使用,若是要导入一个模块中的不少类,使用使用第三种方法,若是是指导入一个模块的一两个类,则可使用第二种方法具体指明。
在包(package)的状况下,若是知道父模块的名称,那么就可使用相对导入。好比当前在products模块下工做,想从隔壁的database模块导入Database类,就可使用相对导入:
from .database import Database # 点号表示使用当前路径的database模块
若是咱们正在编辑ecommerce.payments包里的paypal模块,须要引用父包里的database模块:
from ..database import Database # 使用两个点号表示访问上层的父类
若是ecommerce有contact包,该包里有email模块,须要将该模块的sendEmail函数导入到paypal模块中,
from ..contact.email import sendEmail
大部分的面向对象的编程语言都有一个“访问控制”的概念,好比私有的(private)、受保护的(protected)和公共的(public)。但python并无这种强制规定。在技术层面上,一个类里的全部方法和属性都是公共可访问的,如下有三种形式建议不一样的访问形式:
一、使用注释进行提示建议。如能够在docstring里面放一个提示来代表这个方法只是内部使用的
二、给某个属性或者方法加一个下划线的前缀,大部分python程序员会把这个解释为“这是个内部变量,使用以前要三思”
三、给某个属性或者方法添加一个双下划线的前缀,强烈建议为内部变量。访问时须要名称改编(name mangling),即在该方法或者属性前面自动加一个_<classname>的前缀(单下划线)。
通常状况下,不会使用加下划线或者双下划线的变量。
class SecretString: ''' A not-at-all secure way to store a secret string''' def __init__(self, plain_string, pass_phrase): self.__plain_string = plain_string self.__pass_phrase = pass_phrase def decrypt(self, pass_phrase): ''' Only show the string if the pass_phrase is correct.''' if pass_phrase == self.__pass_phrase: return self.__plain_string else: return
将上述代码存储为filename.py,而后使用python -i filename.py执行这个脚本,而后在交互的解释器里进行以下的测试:
>>> secret_string = SecretString("ACME: Top Secret", "antwerp") >>> print(secret_string.decrypt("antwerp")) ACME: Top Secret >>> print(secret_string.__plain_text) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'SecretString' object has no attribute '__plain_text' >>> print(secret_string._SecretString__plain_string) ACME: Top Secret
在ecommerce包里有两个模块,一个是database.py,另外一个是products.py,假设database里面有一个db变量,这个变量在不少地方都会被访问,那么咱们下面的代码将能够实现用import ecommerce.db取代import ecommerce.database.db。
经过在__init__.py文件(定义目录为包),在这里文件中能够包含任意变量或者类的生命,并且它会做为这个包的一部分被咱们使用。在这个例子中,若是有ecommerce/__init__.py文件里包含这么一行:
from .database import db
那么咱们就能够用下面的语句,在mian.py或者其余文件访问这个db属性了:
from ecommerce import db
若是你把全部代码放在了一个单独的模块,以后又决定拆成一个包里的多个包,__init__.py文件一样对你有帮忙。
其余模块若是想要访问这个新包,__init__.py文件仍然是主要的切入点。可是在内部,代码仍然能够被组织成许多不一样模块或者子包。
原文连接: