質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

4回答

1372閲覧

Pythonでクラスを変数に代入する場合の命名規則について

kairi003

総合スコア1332

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/07/16 11:05

編集2021/07/16 11:18

Pythonの命名規則について,PEP8では変数は小文字スネークケース,クラスはパスカルケースとされていますが,変数にインスタンスではなくクラスを代入したい場合はどちらを使用するのがよいのでしょうか.

具体的には

py

1class BarBase(metaclass=ABCMeta): 2 pass 3 4class Bar1(BarBase): 5 pass 6 7class Bar2(BarBase): 8 pass

に対して,

py

1class Foo: 2 def __init__(self, bar: BarBase): 3 self.bar = bar 4 def method(self): 5 return self.bar()

とするべきか

py

1class Foo: 2 def __init__(self, Bar: BarBase): 3 self.Bar = Bar 4 def method(self): 5 return self.Bar()

とするべきかで悩んでいます.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

クラス名がキャメルケースであることが望まれるのは「クラスの名前」であって、「クラスを束縛する変数の名前」ではないでしょう。

python

1>>> class Foo: 2... pass 3... 4>>> Foo().hoge() 5Traceback (most recent call last): 6 File "<stdin>", line 1, in <module> 7AttributeError: 'Foo' object has no attribute 'hoge'

のケースの例外のメッセージ部分、"Fooオブジェクトは属性hogeを持ってない"の所にあらわれるのが、「クラスの名前」です。
「クラスを束縛する変数の名前」がここにあらわれることはないです。

python

1>>> foo_is_foo = Foo 2>>> foo_is_foo().hoge() 3Traceback (most recent call last): 4 File "<stdin>", line 1, in <module> 5AttributeError: 'Foo' object has no attribute 'hoge'

のようにTraceback上に変数の名前が出たりはしないので、代入文でクラスを扱うぶんには、変数名をキャメルケースにする必要はなくスネークケースにする方が自然かと思ってます。

投稿2021/07/17 03:20

quickquip

総合スコア11235

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

はじめにには以下のように書かれています。

多くのプロジェクトには、自分たちのコーディングスタイルに関するガイドラインがあります。それとこの文書の規約の内容が矛盾した場合は、そのプロジェクトのガイドラインが優先します。

一貫性にこだわりすぎるのは、狭い心の現れであるには以下のように書かれています。

スタイルガイドは一貫性に関するものです。このスタイルガイドに合わせることは重要ですが、プロジェクトの中で一貫性を保つことはもっと重要です。一番重要なのは、特定のモジュールや関数の中で一貫性を保つことです。

しかし、一貫性を崩すべき場合があることも知っておいてください - つまり、このスタイルガイドが適用されない場合があります。疑問に思ったときは、あなたの判断を優先してください。他の例を調べ、一番良さそうなものを決めて下さい。そして、躊躇せずに質問して下さい!

今回のご質問は、どちらのルールを優先すべきかですが、基本的にはkairi003あるいはkairi003さんが参加しているプロジェクトで決めるべき問題であると思われます。

その前提としてPythonの変数とは何か、Pythonのクラス名とは何かを理解しておいてください。

クラスには二つの名前があります。

ひとつはクラスが生成されるときにそのクラスオブジェクトの属性である名前です。
これは以下の方法で確認できます。

Python

1>>> class Foo(): 2... pass 3... 4>>> print(MyClass.__name__) 5Foo

もう一つは、生成されたクラスオブジェクトが束縛されている変数名です。

4.2. 名前づけと束縛 (naming and binding)には以下のように書かれています。

以下の構造で、名前が束縛されます: 関数の仮引数 (formal parameter) 指定、 import 文、クラスや関数の定義 (定義を行ったブロックで、クラスや関数名を束縛します)、代入が行われるときの代入対象の識別子、 for ループのヘッダ、 with 文や except 節の as の後ろ。 "from ... import *" 形式の import 文は、 import されるモジュール内で定義されている、アンダースコアから始まるもの以外の全ての名前を束縛します。

つまり、Fooという変数には上記のクラスオブジェクトが束縛されています。

Fooはクラスの名前属性でもあり、変数名でもあります。

Bar = Foo

とするのは、FooもBarも変数名であるという考え方から妥当です。

bar = Fooとするのはクラス定義以外の方法で定義した変数名という考え方から妥当です。

どちらを選択しても良いというのが私の意見です。

投稿2021/07/16 12:30

ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lehshell

2021/07/16 13:02

細かい話ですが、引用されている説明から Fooという変数には上記のクラスオブジェクトが束縛されています。 については 上記のクラスオブジェクトにはFooという変数が束縛されています。 ではありませんか?
ppaul

2021/07/16 14:58

英語では、The following constructs bind names: formal parameters to functions, import statements, class and function definitions (these bind the class or function name in the defining block), and targets that are identifiers if occurring in an assignment, for loop header, or after as in a with statement or except clause. The import statement of the form from ... import * binds all names defined in the imported module, except those beginning with an underscore. ですので、厳密にいうと、Fooという名前が上記のクラスオブジェクトに束縛されている、ですね。 「上記のクラスオブジェクトにはFooという変数が束縛されています。」という言い方だと、複数の名前が同じオブジェクトに束縛されることが可能であるというニュアンスを伝えにくいように思います。
lehshell

2021/07/16 16:42

同意します。
quickquip

2021/07/17 03:18

文章を読んでいる分にはそんな感覚があることは同意ですが、 ・1つの名前が複数のオブジェクトと結びつくことはない ・1つのオブジェクトが複数の名前と結びつくことはある からこそ「名前がオブジェクトに束縛されている」のではないでしょうか。
guest

0

PEP8だと、変数の命名規則において命名先の種別ごとにどうするべきかという分岐は「型変数はアッパーキャメル」ぐらいしか載ってなさそうなので、自分はPEP8準拠として基本的にはスネークケースで書きます。

また、自分の記憶上の話にはなりますが、
上記を前提として、クラスオブジェクト(≠インスタンス)であることを明示させたいなら、
多少冗長ですが役割_classという変数にしちゃうことがあります。

python

1class Foo: 2 def __init__(self, bar_class: BarBase): 3 self.bar_class = bar_class 4 5 def method(self): 6 return self.bar_class()

投稿2021/07/16 11:24

attakei

総合スコア2740

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

クラスを代入しようがそれは(ナカミがインスタンスなだけの)変数です

投稿2021/07/16 11:07

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問