可以用 Python 寫只暴露一個 function 的模塊嗎?

就像nodejs的一些模塊兒(when,epress,parsems),只暴露一個function,或者模塊兒本身能夠被當做函數調用。


如果你是問在 module 中定義多個函數並選擇性地暴露其中一個的話,答案是「嚴格來說不可以」。你可以用單下劃線來定義 module 的私有成員,從而防止它們被自動導入:

#file test.py
def foo():
print foo

def _bar():
print _bar

此時 from test import * 只會導入 foo,而 import test 只會導入 test.foo 。但是你仍舊無法阻止別人顯式地 from test import _bar 。詳細原因參見 一個 Pythonic 的類應不應該在 __init__ 中檢查參數有效性? 中的答案。

又或者你可以只在 module 里定義單一一個函數,所需其他函數均在此類中定義。

#file test.py
def foo():
def bar():
print bar in foo
bar()

又或者既然 class 可以寫成 callable 的,那也可以當作函數用:

#file test.py
def Foo(object):
def __call__(self):
print "foo"

#__main__:
&>&>&> from test import *
&>&>&> f = Foo()
&>&>&> f()
foo

Python 裡面 module 不能成為 callabe object,所以如果要讓 module 能當函數用,必須自己去改被 import 進去的 namespace 的模塊列表:

#test.py
import sys
def foo():
print "foo"
sys.modules[__name__] = foo

#__main__:
&>&>&> import test
&>&>&> test()
foo

這樣做太過 hacky,請不要這樣做。

當然還有更 hacky 的方法:CPython 判斷某 object 是否 callable,是查看其類型之 _typeobject 成員的 tp_call 函數指針是否為 NULL(見 cpython: 8d4cace71113 Objects/abstract.c )。那麼就可以利用 ctypes 級別修改 module 依賴的 PyTypeObject,使其 tp_call 指針指向有意義的函數,從而讓 module 也變得 callable,詳見 http://www.slideshare.net/r1chardj0n3s/dont-do-this-24000445 第70頁開始的內容。但是也請不要這樣做。


推薦閱讀:

現在學編程,晚么?
C++中關於跨平台中子線程式控制制的一些心得(2):用於線程的同步的Async容器
如何學好c語言?
工作一個月的感受
怎樣在多台Web伺服器上共享Session

TAG:Python | 編程 | Nodejs |