假設有一個 hello.py 的模塊,當我們從別的模塊調用 hello.py 的時候,會發生什么呢?
方便起見,我們之間在 hello.py 的目錄下使用 ipython 導入了。
hello.py 的代碼如下,分別有模塊變量,函數,類變量,類的靜態方法、類方法和實例方法。
# hello.py
print 'module value'
module_a = 233
def f():
print 'func name:', f.__name__
class DoClass(object):
print 'do class'
c_value = 88
@classmethod
def cf(cls):
print 'cf', cls.cf
@staticmethod
def sf():
print 'sf', DoClass.sf.func_name
def f(self):
print self.f
在 hello.py 的目錄下,開啟 ipython,查看結果。
In [1]: import sys
In [2]: sys.modules['hello']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-2-ec73143594c2> in <module>()
----> 1 sys.modules['hello']
KeyError: 'hello'
在還沒有導入 hello 模塊的時候,可以看到,此時系統中是沒有這個模塊的,讓我們進行一次導入。
In [3]: import hello
module value
do class
In [4]: sys.modules['hello']
Out[4]: <module 'hello' from 'hello.pyc'>
導入后,可以看到模塊中的模塊變量和類變量都直接執行了,並且可以看到此時系統中是有了 hello 這個模塊了。此時可以看一下 hello 模塊的屬性:
In [5]: dir(hello)
Out[5]:
['DoClass',
'__builtins__',
'__doc__',
'__file__',
'__name__',
'__package__',
'f',
'module_a']
可以看到,模塊有模塊變量、函數以及類三個屬性。此時,在 ipython 中再次導入 hello,查看結果:
In [6]: import hello
In [7]:
發現此時什么都沒有輸出,這是因為模塊只有第一次被導入的時候才會被執行。其實,可以把導入模塊作為生成一個新的對象,模塊變量和類變量都是在模塊對象初始化的時候執行的,而函數和類的方法,則不會初始化的時候執行,只有在調用的時候才會執行:
In [7]: hello.f()
func name: f
In [8]: hello.module_a
Out[8]: 233
In [9]: hello.DoClass
Out[9]: hello.DoClass
In [10]: hello.DoClass.c_value
Out[10]: 88
那么,如果在你模塊中導入了其他的模塊,或者導入了其他模塊的方法,又是怎樣的呢?
# hello.py
# -*- coding: utf-8 -*-
import math
from math import sqrt
在模塊中導入 math 以及 math 的 sqrt 方法,然后導入 hello:
In [1]: import hello
In [2]: dir(hello)
Out[2]:
['__builtins__',
'__doc__',
'__file__',
'__name__',
'__package__',
'math',
'sqrt']
In [3]: hello.math
Out[3]: <module 'math' from '/usr/local/Cellar/python/2.7.14_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/math.so'>
In [4]: hello.math.sqrt(100)
Out[4]: 10.0
In [5]: hello.sqrt(1000)
Out[5]: 31.622776601683793
可以看到,導入 hello 后,在 hello 中導入的 math 以及 sqrt 都成了 hello 的方法,這和我們直接在模塊中定義的變量是一致的。
總結:不管在模塊中導入其他的模塊或者直接定義變量,函數以及類,擋在別的模塊中導入該模塊的時候,這些內容都將成為該模塊的屬性。這其實和 Python 中一切皆對象是保持一致的。