コードガイド.

本節では、コアパッケージと協調パッケージの両方が従うべき要求および基準を紹介し、付属パッケージについてもこれらの要求および基準に従うことを提案する。

インターフェースと依存項

  • 全てのコードは python_requires キー入力. setup.cfg コアバッグのファイルです。

  • Usage of six, __future__, and 2to3 is no longer acceptable.

  • f-strings 可能な場合には使用され、そうでなければPython 3フォーマットが使用されなければなりません(すなわち "{{0:s}}".format("spam") )ではなく % 演算子. ("%s" % "spam" )。

  • コアパッケージは、Astropyコアに既存のコンポーネントを除いて導入可能であるべきである( Python Standard Library そして、 NumPy 1.17 あるいは遅い時期。

  • 他の依存項-例えば SciPy, Matplotlib, または他の第三者パッケージ−サブモジュールのための、または関数呼び出しのための使用を可能にするが、パッケージ文書に明記されなければならず、関連するコンポーネントのみに影響を与えるべきである。関数および方法では、オプションの依存項は通常のものを使用すべきである import この文は ImportError もし依存項が利用できなければ。Astpyコアパッケージでは、このようなオプション依存項は、 setup.cfg 書類の中の extras_require 入る。

    モジュールレベルでは,オプション依存項からクラスを派生することができるサブクラスは,以下のようになる.

    try:
        from opdep import Superclass
    except ImportError:
        warn(AstropyWarning('opdep is not present, so <functionality>'
                            'will not work.'))
        class Superclass(object): pass
    
    class Customclass(Superclass):
        ...
    
  • パケットまたはサブパッケージに必要であるが、パケットに特定されない汎用ユーティリティは、 packagename.utils モジュール(例えば astropy.utils コアパックに使用されています)。もしすでに実用的なプログラムが存在すれば astropy.utils パッケージは常に実用的なプログラムを使用しなければなりません packagename.utils モジュールです。

文書とテスト

  • 文書文字列はすべての共通クラス/メソッド/関数に存在しなければならず、従わなければならない 文書を作成する 書類です。

  • 可能な限りすべてのクラスや関数の文書文字列に用法例を作成する.これらの例は、ユーザがワード毎にコピーして実行することができるはずである、短く、容易にコピーされるべきである。可能であればこれらの例は doctest フォーマットは,テストキットの一部として実行される.

  • ユニットテストは、可能な限り多くの共通方法および関数のために提供されるべきであり、従うべきである。 テストガイド. 書類です。

データと構成

  • パケットは名前のディレクトリにデータを含むことができます data サブルーチンソースディレクトリでは,約100 kB以下であればよい.これらのデータは常に get_pkg_data_fileobj() あるいは…。 get_pkg_data_filename() 機能します。データがこのサイズを超える場合、ソースコード·リポジトリの外にホストされるか、internet上のサード·パーティにホストされるか、またはホストされるべきである。 astropy data server それがそうです。いずれの場合も常に使用すべきである get_pkg_data_fileobj() あるいは…。 get_pkg_data_filename() 機能します。特定のバージョンのデータファイルが必要な場合は、中に紹介したハッシュ機構をご利用ください astropy.utils.data 使うべきです。

  • 永続的な構成はすべて使用しなければなりません システムを構成する (astropy.config ) 仕組みです。このような構成項目は、それらを使用するモジュールまたはパケットの上部に配置され、ユーザが設定変更の内容を知ることができる十分な説明を提供するべきである。

標準出力、警告、エラー

内蔵の print(...) 関数は、例えば、ユーザ明示的要求の出力のためにのみ使用されるべきである print_header(...) あるいは…。 list_catalogs(...) それがそうです。他の標準出力、警告、およびエラーは、以下の規則に従うべきである。

  • For errors/exceptions, one should always use raise with one of the built-in exception classes, or a custom exception class. The nondescript Exception class should be avoided as much as possible, in favor of more specific exceptions (IOError, ValueError, etc.).

  • 警告に対しては常に使用すべきである warnings.warn(message, warning_class) それがそうです。これらの内容は再定義されます log.warning() デフォルトの場合、標準的な警告捕捉機構およびカスタム警告クラスを使用することができる。警告類は AstropyUserWarning それを継承したりします

  • 情報性メッセージとデバッグメッセージについては,つねに使用すべきである. log.info(message) そして log.debug(message) それがそうです。

ログ記録システムは、内蔵されたPythonを使用します。 logging モジュールです。以下のコマンドを使用してレコーダを導入することができる。

from astropy import log

コードスタイル/約束

  • コードは標準に従うべきだ PEP8 Style Guide for Python Code それがそうです。特に,これには4つのスペースのみを用いてインデントを行うことが含まれており,タブを使用していない.

  • 我々のテストインフラストラクチャは現在,PEP 8スタイルガイドのサブセットを実行している.以下のコマンドを実行することで、ローカルで変更がこれらのルールに従うかどうかをチェックすることができます tox 命令::

    tox -e codestyle
    
  • 既存のコードスタイルに従う サブパックでは,純粋なスタイル変更を避ける.特に、異なるサブパック(通常は80文字または100文字)の最大行長が異なる。コードを追加したり修正したりするときはできるだけスタイルを保ってください。

  • 自動コードフォーマット化器(例えば、 Black )Astropyへの寄付に強く反対します。

  • PEP 8の提案によると、絶対輸入が一般的に使われています。例外的な場合はフォームの相対導入である. from . import modname 同一サブモジュール中のファイルを参照する際に用いることが望ましい.これは、別のサブモジュールからではなく、前のサブモジュールからのコードをより明確にする。

    注釈

    コードのPEP 8互換性をテストするためのオプションが複数ありますので、参照されたい テストガイド. より多くの情報を得ることができます参照してください 以下の符号化ガイドに対するEmacs設定 PEG 8に準拠するEmacsのいくつかの構成オプションの確保を支援するために使用される。

  • Astropyソースコードは、ファイルの先頭に注釈を含むべきである(またはそれに続く) #!/usr/bin env python コマンド)は,Astropyソースコードを指すライセンスである.このたびは次のようにすべきである.

    # Licensed under a 3-clause BSD style license - see LICENSE.rst
    
  • 以下の命名約束:

    import numpy as np
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    

    関連するところで使用すべきです。一方:

    from packagename import *
    

    フラット化モジュールの名前空間のツールとして使用しない限り,絶対に使用しない.使用が許可されている例を示す 受け入れ可能な使用 from module import * 例を挙げましょう

  • クラスは、直接変数アクセスを使用するか、Pythonの属性機構を使用してオブジェクトインスタンス変数を設定すべきです。 get_value/set_value スタイル方法は、取得および設定値がオーバーヘッドの大きい操作を計算する必要がある場合にのみ使用されるべきである。♪the 属性と get_/set_ 以下の例は、この基準を示す。

  • クラスは内蔵を使用すべきである super() 関数がそれらのハイパークラス中のメソッドを呼び出す際には,特殊な理由がない限りそうしない. super() そうでなければ機能しないので、すべてのサブクラスで一貫して使用されなければならない。♪the Super()と直接呼び出し 以下の例はなぜこれが重要なのかを示している.

  • 一般に,十分な理由がない場合には多重継承を避けるべきである.多重継承をうまく実現することは困難であり,これが多くのオブジェクト指向言語(たとえばJava)が多重継承をまったく許さない理由である.Pythonは実際に C3 Linearization アルゴリズムは,一致した方法でランキングを解析する.十分な理由がない,あるいはC 3をどのように用いてメソッド解析順序を決定するかが理解されていなければ,非平凡な多重継承プランを試みるべきではない.しかし、直交基底クラスを用いた簡単な多重継承を用いて、“混合”モードと呼ぶことができる。

  • __init__.py モジュールのファイルには、いかなる重要な実装コードも含まれてはならない。 __init__.py しかしながら、組織モジュールレイアウトのための文書文字列およびコード(例えば、 from submodule import * 上記の基準と一致する).モジュールが十分に小さく,1つのファイルに入れることができる場合,それは含まれているのではなく,1つのファイルにすぎないはずである. __init__.py ファイルです。

  • 命令は従うべきだった コマンドラインスクリプトを作成する 書類です。

Unicode基準

最大互換性を得るためには,非ASCII文字をコンソールやファイルに書き込むことが機能しないと仮定する必要がある.しかし,正しく構成されたUnicode環境を持つユーザに対しては,Unicodeを用いて出力するために適切なときに参加を選択することを許可すべきである.グローバル構成オプションがあります astropy.conf.unicode_output Unicode出力値を有効にするには、設定してください False デフォルトの場合。

The following conventions should be used for classes that define the standard string conversion methods (__str__, __repr__, __bytes__, and __format__). In the bullets below, the phrase "string instance" is used to refer to str, while "bytes instance" is used to refer to bytes.

  • __repr__ :7ビットの文字のみを含む文字列インスタンスを返します。

  • __bytes__ :7ビットの文字のみを含むバイトインスタンスを返す.

  • __str__ :文字列インスタンスを返します。もし…。 astropy.conf.unicode_output はい。 False 7ビットの文字だけが含まれていなければなりません。もし…。 astropy.conf.unicode_output はい。 True これには,非ASCII文字が含まれている可能性がある(適用すれば).

  • __format__ :文字列インスタンスを返します。もし…。 astropy.conf.unicode_output はい。 False 7ビットの文字だけが含まれていなければなりません。もし…。 astropy.conf.unicode_output はい。 True これには,非ASCII文字が含まれている可能性がある(適用すれば).

文字列(Unicodeまたはバイト)を往復する必要があるクラスについては,解析器は受け入れなければならない __str__ それがそうです。また、 __repr__ 意味のある時に往復すべきです。

このデザインは基本的にボステルの法則に従っています“受信は寛大で送信は保守的”

以下の例示的なクラスは、これを実現する方法を示す。

# -*- coding: utf-8 -*-

from astropy import conf

class FloatList(object):
    def __init__(self, init):
        if isinstance(init, str):
            init = init.split('‖')
        elif isinstance(init, bytes):
            init = init.split(b'|')
        self.x = [float(x) for x in init]

    def __repr__(self):
        # Return unicode object containing no non-ASCII characters
        return f'<FloatList [{", ".join(str(x) for x in self.x)}]>'

    def __bytes__(self):
        return b'|'.join(bytes(x) for x in self.x)

    def __str__(self):
        if astropy.conf.unicode_output:
            return '‖'.join(str(x) for x in self.x)
        else:
            return self.__bytes__().decode('ascii')

またテスト助手もいます astropy.test.helper.assert_follows_unicode_guidelines クラスが上述したUnicode基準に従うことを確実にする。以下の例示的なテストでは、上の例のクラスが適合するかどうかをテストします。

def test_unicode_guidelines():
    from astropy.test.helper import assert_follows_unicode_guidelines
    assert_follows_unicode_guidelines(FloatList(b'5|4|3|2'), roundtrip=True)

Cコードを含む

  • C拡張が純粋なPythonよりも顕著な性能向上を提供するか、または必要な機能を提供するためにロバストなCライブラリが存在する場合にのみ、C拡張の使用が許可されます。C拡張を使用する場合、Pythonインターフェースは前述のPythonインターフェース基準に適合しなければなりません。

  • はいの使用 Cython C拡張に使用することを強く提案する. Cython 拡張名は保存する必要があります .pyx ソースコード格納ライブラリ内のファイルですが、生成されたものではありません .c ファイルです。

  • C拡張が外部Cライブラリに依存する場合、ライブラリのソースコードは、CライブラリのライセンスがAstropyライセンスと互換性があることを前提として、Astropyコアとバンドルされるべきである。さらに、ソフトウェアパッケージは、Astropyに含まれるライブラリの代わりにシステムインストールライブラリを使用することと互換性がなければならず、パッケージをインストールするユーザは、システムバージョンを使用することを選択することができるはずである。 ASTROPY_USE_SYSTEM_??? 環境変数、その中で ??? ライブラリの名前です例えば ASTROPY_USE_SYSTEM_WCSLIB (別途参照) 外部Cライブラリ )。

  • C拡張が必要な場合 Cython 使えないならば PEP 7 Style Guide for C Code おすすめです。

  • C拡張 (Cython または他の)拡張モジュールを構築するために必要な情報は、本明細書に記載されたメカニズムによって提供されるべきである CまたはCython拡張 それがそうです。

特別に付属コースのご希望を承っております

  • 関連するパケット自体とは無関係な多くのクラス/機能を実装する関連パケット(例えば、前のパケットのレガシーコード)は受け入れられず、このパケットは、必要な機能および関連拡張のみを含むべきである。

  • 付属パッケージは Python Package Index ソースパケットをダウンロードしてインストールするための適切なメタデータを有する。

  • ♪the astropy ルートパッケージ名は、関連するパッケージによって使用されるべきではありません-コアパッケージの使用のために保持されています。

実例.

本節では,いくつかの例を示す(すべての例が正しいわけではない!)ガイドラインの観点を説明するために。

属性と get_/set_

この例は、getter/setterメソッドではなく、属性を使用するためのガイドラインを示す例示的なクラスを示す。

あなたが定義したとしましょう Star クラスを作成し、以下の例を作成します。

>>> s = Star(B=5.48, V=4.83)

あなたは常に次のような属性文法を使用しなければなりません。

>>> s.color = 0.4
>>> print(s.color)
0.4

このようなものではありません

>>> s.set_color(0.4)  # Bad form!
>>> print(s.get_color())  # Bad form!
0.4

Python属性を使用しても、属性文法はget/set方法で任意の可能な操作を実行することができます。しかし,冗長や複雑な計算については,以下の方法を用いてください.

>>> print(s.compute_color(5800, age=5e9))
0.4

Super()と直接呼び出し

この例はなぜ使用されるのかを示している super() 多重継承の場合,超クラスを手動で呼び出すメソッドよりもメソッド解析手順が一致する:

# This is dangerous and bug-prone!

class A(object):
    def method(self):
        print('Doing A')


class B(A):
    def method(self):
        print('Doing B')
        A.method(self)


class C(A):
    def method(self):
        print('Doing C')
        A.method(self)

class D(C, B):
    def method(self):
        print('Doing D')
        C.method(self)
        B.method(self)

その後、以下の動作が実行される場合:

>>> b = B()
>>> b.method()

ご覧のように

Doing B
Doing A

これはあなたが望むものであり、C言語についても同様である。しかし、以下の操作が実行される場合:

>>> d = D()
>>> d.method()

D、B、C、Aの順に呼び出される方法を見たいかもしれませんが、ご覧になるでしょう。

Doing D
Doing C
Doing A
Doing B
Doing A

どちらも B.method() そして C.method() 呼び出しをする. A.method() それらが階層構造中のリンクの一部として呼び出されていることは意識されていない.いつですか C.method() 呼び出された場合,この2つのクラスから継承されたサブクラスから呼び出されたことは知られていない. B そして C それは B.method() 次はこれを呼ぶべきです。呼び出しで super() 全体的な解析手順を示しています D 予想されており,各スーパークラスは連携して次のスーパークラスにどのクラスに制御権を渡すべきかを決定することができる. super() 電話:

# This is safer

class A(object):
    def method(self):
        print('Doing A')

class B(A):
    def method(self):
        print('Doing B')
        super().method()


class C(A):
    def method(self):
        print('Doing C')
        super().method()

class D(C, B):
    def method(self):
        print('Doing D')
        super().method()
>>> d = D()
>>> d.method()
Doing D
Doing C
Doing B
Doing A

ご覧のように、各スーパークラスの方法は一度だけ入力されます。そのために重要な点は,そのスーパークラスバージョンのメソッドを呼び出すクラスの各メソッドが使用されていることである. super() このメソッドを直接呼び出すのではありません最も一般的な単継承の場合、使用 super() 機能的にはスーパークラスのメソッドを直接呼び出すことに等しい.しかし,クラスが多重継承階層構造で使用されると,それを用いなければならない. super() 階層構造内の他のクラスと協働するために.

注釈

以下の利点の詳細については、参照されたい super() Https://hittinger.wordpress.com/2011/05/26/Super-Seed-Super/を参照

受け入れ可能な使用 from module import *

from module import * 実現コードを含むモジュールでの使用は奨励されないが,解像度を妨げるため,通常は未使用の変数を導入する.しかしながら、以下のようにレイアウトされたパケットに使用することができる。

packagename
packagename/__init__.py
packagename/submodule1.py
packagename/submodule2.py

この場合には packagename/__init__.py そうかもしれません

"""
A docstring describing the package goes here
"""
from submodule1 import *
from submodule2 import *

これにより、サブモジュール内の関数またはクラスが直接使用されることを可能にする packagename.foo ではなく packagename.submodule1.foo それがそうです。この方法を用いれば,サブモジュールの使用が強く推奨される. __all__ 変数はどのモジュールを導入すべきかを指定する.だから、 submodule2.py こう読むかもしれません

from numpy import array, linspace

__all__ = ['foo', 'AClass']

def foo(bar):
    # the function would be defined here
    pass

class AClass(object):
    # the class is defined here
    pass

これは確かに from submodule import * 輸入に限る foo そして AClass でもそうじゃない numpy.array あるいは…。 numpy.linspace それがそうです。

余分な資源

以下には、符号化ガイドに関連するより多くの提示および提示が含まれる。