2009-06-21 8 views
15

これまで、私はperlのAUTOLOAD機能を使ってシンボルの名前空間への遅延ロードを実装しましたが、Pythonでは同じ機能が必要でした。Pythonの自動ロード

伝統的にあなたが得ることができるように見えるのは、この種のことを達成するためにクラスと__getattr__クラスを使用することです。しかし、私はまた、sys.modulesの周り臨検試みたが、これを作ってみた:

# mymod.py 
def greet(greeting="Hello World"): 
    print greeting 

class autoload(object): 
    def __init__(self, __name__): 
     super(autoload, self).__init__() 
     self.wrapped_name = __name__ 
     self.wrapped = sys.modules[__name__] 
    def __getattr__(self, name): 
     try: 
      return getattr(self.wrapped, name) 
     except AttributeError: 
      def f(): 
       greet(name+" "+self.wrapped_name) 
      return f 

if __name__ != "__main__": 
    import sys 
    sys.modules[__name__] = autoload(__name__) 

これは、私は、ユーザーの視点からみたい道に動作しない:

~> python 
Python 2.5.1 (r251:54863, Jan 10 2008, 18:01:57) 
[GCC 4.2.1 (SUSE Linux)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import mymod 
>>> mymod.hello() 
hello 
>>> from mymod import Hello_World 
>>> Hello_World() 
Hello_World 

をしかし、それは私を打ちます - 人々がPythonで自動ロードするために使用する傾向がある標準的なアプローチはありますか?

第2に、経験豊富なPython開発者向けの質問は、実際には「これがあなたを良いか悪い練習として打つのですか」です。私は合理的に経験豊富なPython開発者ですが、それは本当に便利だと思いますが、それは境界線として私を襲って、これが良い練習、悪い練習または同様のものと見なすことができるかどうかに興味があります。

ありがとうございます!

+0

https://stackoverflow.com/questions/2447353/getattr-on-a-module and https://stackoverflow.com/questions/922550/how-to-mark-a-global-as-deprecated-in -pthon/922693#922693 – n611x007

+0

質問テキストとコードとタグの変更が私の元の質問を反映しないため、できればこれを削除します。以下の回答は特に役に立ちません。私は人々が質問文を変更する前に実際に尋ねることを望む。たとえば、元のコードが "mod_name"ではなく "\ _ \ _ name \ _ \ _"を使用した理由は、sys.modules [\ _ \ _ name \ _ \ _]などと直接の類似性を示すことです。これは編集によって破られました。 –

+1

@MichaelSparks:あなたの質問をSilentGhostのマイナー編集に戻しました。うまくいけば、それは今よりよく答えにマッチします。誰も他の人の質問でコードを編集する必要はありません。 –

答えて

10

"レイジーインポート"はPEP 302で指定された "新しいインポートフック"の上に構築でき、今では完全に実装されました。 PEP 369は、「遅延インポート」とポストインポートフックをカバーするために使用されていましたが、その後単純化され、インポート後のフックのみをカバーしています。それでも、あなたはoriginal draftに興味があるかもしれません。

meta_pathフックを介した「遅延インポート」の実装は、this recipeにあります。

-1

いいえ、私は役に立たないと思います。

の場合、モジュールから取得しようとしている属性ごとに関数を作成するのはなぜですか?私は混乱しているようだ。新しい機能が魔法によって作成されているように見えるので、何が起こっているのかを理解するために実装を深く検討しなければなりません。構文上のメリットがないからです。

あなたがそれを実行する正当な理由があったとしても、なぜそれをモジュールで行うのですか? sys.modulesにクラスインスタンスを登録する理由私は、ものが何かを非のところに見えるようにすることは、Pythonでぶち壊されていると思う。

あなたが意図的にコードを難読化していない限り、私はなぜそのすべてをやるのかわかりません。

+2

これは、たとえばインポート時間を最小限に抑えたい場合には、確かに便利です。しかし、それは常に境界線であり、状況がより複雑になります(特にデバッグ)。インポートフックは、すべての状況で正しく取得することは困難です。私は可能な限りそれらの主要な使用の外で使用されることを意図した 'コア'ライブラリを避けるでしょう。 –

+0

Davidさんのコメント+1。遅延読み込みは、モジュールの状態に複雑さを追加します。インポートステートメントを書くのに数分かかることはありますが、デバッグではその時間が失われることは事実です。 ちなみに、最新のIDEの多くには、インポートを管理する機能があります。 Eclipseのpydevをチェックしてください。 –

+3

例えば、関数の名前がURIになるREST APIラッパーのようなものについては、それは完全に便利です。各機能の命名は愚かです。また、各関数名を文字列にすると、ユーザーのコードが読みにくく難しくなります。 –

0

モジュールを偽装するためにクラスを使用しての質問に答えるために:

はい、機能は偶然ではないし。それは2.xシリーズの初期から存在しており、3.xシリーズでも動作しています。

はそれを行うには、いくつかの方法があり、それぞれ1ビット不思議なことになるだろう:

は、遅延読み込みの質問に答えるために。モジュール詐称者を使用するのは良い方法です。

関連する問題