2

私は最初の重要な Python プロジェクトに取り組んでおり、スコープの問題とインクルード ファイルでのコードの実行に問題があります。以前は、私の経験は PHP でした。

私がやりたいことは、多数の構成変数を設定する 1 つのファイルを作成し、それをコード全体で使用することです。また、特定の関数とクラスをグローバルに利用できるようにしたいと考えています。たとえば、メイン ファイルには他の 1 つのファイルが含まれ、そのファイルは一般的に使用される一連の関数 (それぞれが独自のファイル内) と構成ファイルをロードします。これらのロードされたファイル内で、関数と構成変数にもアクセスできるようにしたいと考えています。私がやりたくないのは、残りのすべてを含めるために、ルーチン全体を各 (含まれる) ファイルの先頭に置かなければならないことです。また、これらのインクルード ファイルはさまざまなサブディレクトリにあるため、インポートが非常に困難になっています (特に、すべてのファイルを再インポートする必要がある場合)。

とにかく、私が望むものを達成するためのコードを構築するための最良の方法について、一般的なアドバイスを探しています。

ありがとう!

4

4 に答える 4

6

Python では、さまざまな機能を実装する一連のモジュールを用意し、すべての機能へのアクセス ポイントとなる 1 つのモジュールを用意するのが一般的です。これは基本的にファサード パターンです。

例: 、、およびモジュールfooを含むパッケージを作成しているとします。barbazmoo

~/project/foo
~/project/foo/__init__.py
~/project/foo/bar.py
~/project/foo/baz.py
~/project/foo/moo.py
~/project/foo/config.py

あなたが通常行うことは、次__init__.pyのように書くことです:

from foo.bar import func1, func2
from foo.baz import func3, constant1
from foo.moo import func1 as moofunc1
from foo.config import *

今、あなたが今やっている機能を使いたいとき

import foo
foo.func1()
print foo.constant1
# assuming config defines a config1 variable
print foo.config1

必要に応じて、記述するだけで済むようにコードを整理できます。

import foo

すべてのモジュールの先頭で、すべてにアクセスしますfoo(おそらく「グローバル」などの名前を付ける必要があります)。名前空間が気に入らない場合は、次のこともできます

from foo import *

すべてをグローバルにしますが、これは実際にはお勧めできません。覚えておいてください: 名前空間は素晴らしいアイデアの 1 つです。

于 2009-02-03T15:36:21.187 に答える
1

これは 2 段階のプロセスです。

  1. モジュール globals.py で、どこからでもアイテムをインポートします。
  2. 他のすべてのモジュールで、「from globals import *」を実行します

これにより、これらの名前がす​​べて現在のモジュールの名前空間に取り込まれます。

さて、これを行う方法を説明しましたが、そうしないことをお勧めします。まず第一に、「魔法のように定義された」エンティティの束をローカル名前空間にロードしています。これは、 Zen of Pythonの原則 2 、「明示的は暗黙的よりも優れている」に違反しています。「from foo import *」の代わりに、「import foo」を使用してから「foo.some_value」と言ってみてください。短い名前を使用したい場合は、「from foo import mumble, snort」を使用してください。これらのメソッドはいずれも、モジュール foo.py の実際の使用を直接公開します。globals.py メソッドを使用するのはちょっと魔法すぎます。これに対する主な例外は __init__.py にあります。ここでは、パッケージのいくつかの内部側面を隠しています。

グローバルは、誰がそれらを変更 (または破損) しているのかを突き止めるのが非常に難しいという点で、半悪でもあります。グローバルを取得/設定するための明確に定義されたルーチンがある場合、それらのデバッグははるかに簡単になります。

PHP がこの「すべてが 1 つの大きな幸せな名前空間」という概念を持っていることは知っていますが、それは実際には言語設計の貧弱な成果物にすぎません。

于 2009-02-03T15:36:36.850 に答える
0

私が知る限り、プログラム全体のグローバル変数/関数/クラス/など. は Python には存在せず、すべてが一部のモジュール (名前空間) に「限定」されています。したがって、コードの多くの部分でいくつかの関数またはクラスを使用する場合、1 つの解決策は、「globFunCl」(「グローバル」にしたいすべてのものを定義/インポートする) および「config」(構成を含む)変数) を必要な場所にインポートします。ネストされた名前空間を使用する考えが気に入らない場合は、次を使用できます。

from globFunCl import *

このようにして、名前空間を「非表示」にします (名前が「グローバル」に見えるようにします)。

「残りのすべてを含めるために、各(含まれる)ファイルの先頭にルーチン全体を配置する」ことを望まないということで、あなたが何を意味するのかわかりません。ただし、 Python Packagesを確認してください。簡単に作成できるはずです。

于 2009-02-03T15:35:06.933 に答える
0

これは、どのようにパッケージ化するかによって少し異なります。ファイルまたはモジュールの観点から考えることができます。後者は「よりPythonic」であり、どのアイテムを正確に決定することができます(クラス、関数、変数など、名前が付いたものであれば何でもかまいません)。

基本的なルールは、インポートするすべてのファイルまたはモジュールについて、その名前空間に直接アクセスできるものです。したがって、 myfile.py に定義が含まれdef myfun(...):class myclass(...)いるmyvar = ...場合は、別のファイルからそれらにアクセスできます。

import myfile
y = myfile.myfun(...)
x = myfile.myvar

また

from myfile import myfun, myvar, myclass

重要なのは、インポートを含め、myfile のトップ レベルにあるものすべてにアクセスできることです。したがって、 myfile に が含まれている場合はfrom foo import barmyfile.barも利用できます。

于 2009-02-03T15:47:01.823 に答える