web-dev-qa-db-ja.com

定数変数python 3を定義する最良の方法は何ですか

私はpythonで多くの定数変数を含むプログラムを書いています。多くの#defineを含むCの.hファイルのようなこれらすべての変数を保持するファイルを作成したいと思います。 configparser を使用しようとしましたが、使いやすくて楽しいとは思いませんでした。

もっと良い方法を知っていますか?

9
TomE8

Pythonは、CやC++のような定数宣言を許可しません。

通常、Pythonでは、定数は大文字で表記されます( PEP 8 標準)。これはプログラマーが定数であることを知るのに役立ちます。

MY_CONSTANT = "Whatever"

私が使用していないが聞いたことがある別の有効な方法は、メソッドを使用することです:

def MY_CONSTANT():
    return "Whatever"

理論的には、MY_CONSTANT()の呼び出しは定数のように機能します。

編集

コメントが言うように、誰かが呼び出して値を変更することができます

MY_CONSTANT = lambda: 'Something else'

同じ人が最初の例でMY_CONSTANT = "Something else"を呼び出して初期値を変更できることを忘れないでください。どちらの場合も、可能性は低いですが可能です。

16
scharette

Pythonには定数はありません。CやJavaに存在する方法です。関数によってそれらを模倣することができます:

def FOO():
  return "foo"

関数呼び出しをプロパティでラップして、変数のように見せることができます。

class Const:
  @property
  def FOO(self):
    return "foo"

CONST = Const()  # You need an instance

if something == CONST.FOO:
  ...

少しメタを使用すると、簡潔な構文で設定できない属性を取得できます。

def const(cls):
    # Replace a class's attributes with properties,
    # and itself with an instance of its doppelganger.
    is_special = lambda name: (name.startswith("__") and name.endswith("__"))
    class_contents = {n: getattr(cls, n) for n in vars(cls) if not is_special(n)}
    def unbind(value):  # Get the value out of the lexical closure.
        return lambda self: value
    propertified_contents = {name: property(unbind(value))
                             for (name, value) in class_contents.items()}
    receptor = type(cls.__name__, (object,), propertified_contents)
    return receptor()  # Replace with an instance, so properties work.


@const
class Paths(object):
    home = "/home"
    null = "/dev/null"

これで、通常の値としてPaths.homeにアクセスできますが、それに割り当てることはできません。複数の@constファイルを使用する可能性があるため、.hで装飾された複数のクラスを定義できます。

7
9000

次のようなものを使用できます。

ファイル構造:

myapp/
    __init__.py
    settings.py
    main.py

settings.py

CONST_A = 'A'
CONST_B = 'B'

__init__.py

from . import settings as global_settings


class Settings:

def __init__(self):
    for setting in dir(global_settings):
        if setting.isupper():
            setattr(self, setting, getattr(global_settings, setting))

def __setattr__(self, attr, value):
    if not getattr(self, attr, None):
        super().__setattr__(attr, value)
    else:
        raise TypeError("'constant' does not support item assignment")


settings = Settings()

main.py

import settings

print(settings.CONST_A)  # prints A

settings.CONST_A = 'C'  # raises TypeError error

print(settings.CONST_A)  # prints A

settings.CONST_C = 'C'  # also able to add new constants
print(settings.CONST_C)  # prints C

Settingsクラスの__setattr__を上書きすると、すべての属性が読み取り専用になります。唯一の要件は、すべての定数をsettings.pyに大文字で記述することです。ただし、変数を直接インポートすると動作しないことに注意してください。

from settings import CONST_A

print(settings.CONST_A)  # prints A

settings.CONST_A = 'C'  # sets C

print(settings.CONST_A)  # prints C
2
Artem Nepo

Pythonは前処理されていません。ファイルconstant.pyを作成するだけです

#!/usr/bin/env python
# encoding: utf-8
"""
constant.py
"""

MY_CONSTANT = 50

以下の例のような定数値が必要な場合は、constant.pyファイルをインポートします。

#!/usr/bin/env python
# encoding: utf-8
"""
example.py
"""
import constant
print constant.MY_CONSTANT * 2

このようにして、プロジェクト全体で定数を使用できます。

定数が特定のクラスに関連付けられており、そのクラス内でプライベートに使用されている場合、そのクラスに固有のものにするオプションもあります:

class Foo(object):
   GOOD = 0
   BAD = 1

   def __init__(self...

モジュール全体を定義して使用する場合は、モジュールの上に配置します

PIE = 3.47

class Foo(object):
   def __init__(self...
0
Ankireddy

Constants.pyファイルを定義して、すべての定数を記述するだけです。 Pythonには他に手品はありません。一般的な規則としてキャップを使用します。

0
saran3h