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

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

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

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

Python

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

Q&A

解決済

4回答

2238閲覧

Pythonプログラミングの慣習について

退会済みユーザー

退会済みユーザー

総合スコア0

Python 3.x

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

Python

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

2グッド

3クリップ

投稿2019/08/03 03:14

編集2019/08/03 05:42

疑問

  1. Pythonにおける一般的なクラスとdataclassをどのように使い分けるのか?

1-1. 一般的なクラスで実装することを選択する(dataclassに対する)メリットは何か?
2. クラスではなく、トップレベルで関数を定義するのはどのようなときか?
3. ユーティリティクラスやインスタンスの変数を参照しないメソッドを作ることについてどのように考えるか?
3-1. Pythonでは一般的なのか?

現在の考え

  • 基本的にdataclassで実装する
  • また、基本的にfrozen=Trueで実装することで極力イミュータブルにする
  • トップレベルの関数を作ることにやや抵抗がある(Javaなど他の言語が原因?
  • 関数とユーティリティクラスは禁止 - 株式会社アークシステム(infoARK)」を読んでなるべく、作らないようにしてきた。しかし、上同様、Pythonでは話が変わってくるのではないかと思うようになった
nico25, LouiS0616👍を押しています

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

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

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

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

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

guest

回答4

0

1について

dataclassは一種の糖衣構文的な機能なので、これまでの通常のクラス定義でも書いていたor書こうと思っていたものを自動生成してくれるだけです。

dataclasses --- データクラス — Python 3.7.4 ドキュメント

python 3.7以前で稼働させないのであれば、ゴリゴリ使っても誰も怒らないと思います。

immutableにするかどうかは、慎重に考えた上でimmutableのメリットが活かせるかどうかで決めないといけません。なんでもimmutable的な発想には反対します。

2について

あえてオブジェクトにしなくていいようなときはすべてトップレベル関数、という方針もありえます。疎結合の関数でうまく書ければ。

個人的には、クラスを自分で書くときはちょっと覚悟を固めます。だからなんだという話ですが。そんなにしょっちゅうはクラスをいじりたくない、ということです。

3について

Javaなどではそうするしかない面もありますが、pythonの場合はモジュールが気楽に作れてその中にトップレベル関数も作れるので、それでいいと思います。

非クラスベース的な設計も受け入れる懐の深い言語なので、非クラスベース的な設計で書けばいいのです。それでもちゃんと書けばオブジェクト指向プログラミングとして成立するということもあります。
(Pythonを使う限り、すべてがオブジェクトなので)

投稿2019/08/03 06:53

hayataka2049

総合スコア30933

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

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

0

ベストアンサー

1 について

「必要な時に使えば良い」という雰囲気かなと思います。

GitHub に転がっているライブラリを見るとそのへんの雰囲気も掴めるのではないでしょうか。

◯ 機能

dataclasses の主な機能は、よく使うメソッドを変数アノテーションを元に自動的に生成してくれることだと思っています。PEP の Abstract に書いてあります。

◯ 背景

dataclasses と、似たようなライブラリはいくつもあったのに、なぜわざわざ dataclasses を作ったのか? PEP には以下のように書かれています。

One main design goal of Data Classes is to support static type checkers.
Rationale < PEP 557 - Data Classes

FastAPI

しかし、FastAPI という型アノテーションを使っているウェブフレームワークも dataclasses は、特に使っていません。

使わないのに @dataclasses がついていると、どこかで使うのかな?と考えてしまいますね笑

2 について

複数のクラスで使う関数なら使ってもいいかなと思います。

◯ 筆者の意図は...

この記事面白いですね。他も読みました。プライベートメソッドを使うときは他のクラスが隠れているとかも面白かったです。

多人数での大規模な開発を想定する場合、筆者の主張通りトップレベルの関数は確かに書かない方が良い気がします。

たしかに筆者の意図としては「想定されない使われ方をするから」ユーティリティクラスは使うなということだと思います。

例えば自分みたいなテキトーな人間が100人も寄せ集まってトップレベル関数を使っていたら、誰かしら2、3人は想定外な作り方をしそうです、自信があります!笑

クラス定義文を使い名前空間を、きっちり分けて影響範囲を絞っておいた方が安全だと思います。

オブジェクト指向とは個人的に名前空間を分けることだと思っています。

◯ Kotlin について

ただ実際、問題として、どのクラスにも所属しない汎用的な処理を書いた関数は存在します。

わざわざクラスに分けるのは、とても面倒です。そこまで大規模にやらない場合は、厳密に分ける必要もないかなとも思います。

例えば Java は必ずクラスを書かないといけませんが...

java

1// Java 2public class Sample{ 3 public static void main(String args[]){ 4 printSum(3, 4); 5 } 6 public static void printSum(int a, int b){ 7 System.out.println(a + b); 8 } 9}

Java の後継的なポジションにる Kotlin では必ずしもクラスを書く必要がなくなりました。「トップレベルで関数を書けるようになった」ということです。

kotlin

1// Kotlin 2fun main(args: Array<String>) { 3 printSum(3, 4) 4} 5 6fun printSum(a: Int, b: Int) { 7 println(a + b) 8}

「トップレベルで関数を書けるようになった」ということは、絶対に書いてはいけないというわけではないということかなと思います。

3 について

ユーティリティクラスやインスタンスの変数を参照しないメソッドを作ることについてどのように考えるか?

もし複数のクラスで使う「ユーティリティクラス」が存在する場合は、トップレベルで関数を書けばいいと思います。

また、特定のクラスだけで使う「インスタンスの変数を参照しないメソッド」がある場合は staticmethod を使って定義すればいいと思います。

まとめ

質問の意図としては大規模なものでも耐えうる設計がしたいということだと思うのですが、実際の現場などに行ってみないとわからないのかなと思ったりもします。自分もわかりませんが...

個人で勉強されるうちは dataclasses にしても class にしても YAGUNI の精神で肩の力を抜いて tuple, dict, class の順に使えばいいかなと思います。

投稿2019/08/03 08:04

nico25

総合スコア830

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

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

0

JavaだからPythonだからなんて違いはないでしょう。

Javaだって議論は同じで、

https://teratail.com/questions/203779#reply-301210

の質問/回答と根は同じです。

  • 状態を持たず、同じ呼び出しに同じ値を返すような関数
  • オブジェクトを作成する関数
  • インスタンスの状態に紐付かない、外部公開しないような補助関数
  • 多様なオブジェクトに使えるユーティリティ関数

などはモジュールのトップレベルに定義してもぜんぜん構わないでしょう。

Pythonでは、クラスのstaticmethodやclassmethodよりもモジュールのトップレベル関数を好む傾向が強い(感じがする)ぐらいの違いしかないかと思います。

  1. についてはhayataka2049さんと同じ感想なので割愛。

投稿2019/08/03 07:26

quickquip

総合スコア11038

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

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

0

面白そうな話題なので思ったことをつらつらと。

まずdataclassに関しては、まだ慣習と呼べるほど用法用量が定まっていないと感じます。まだ出たてですし。私個人としては、後方互換等を考えるとcollections.namedtupleのほうを推します。読み取り専用属性が多いクラスも、

python

1class Person(namedtuple("_Person", "name age address")): 2 ...

みたいに書いたりします。

次にトップレベルで関数を定義に関しては、私個人としては逆に、クラスの定義よりも頻度が高いです。Pythonはマルチパラダイムなので、私は「クラスは必要になるまで定義しない」派です。

最後にユーティリティクラスインスタンスの変数を参照しないメソッドについては、私は好きではないです。それよりもユーティリティモジュールトップレベルの関数のほうが好きです。

投稿2019/08/03 12:10

YouheiSakurai

総合スコア6142

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問