俺の雑記帳

My random memorandumです。(つまり、個人的な備忘録であり、その点ご容赦を。)

参照渡し,値渡し,参照の値渡し / Pythonはカプセル化できん?(Pythonの独特の哲学)

(この項、まだあんまり整理していない)


■参照渡し?

もう参照渡しとは言わせない - Qiita
https://qiita.com/mdstoy/items/2ef4ada6f88341466783
Java, C#
 コメントなどにPythonなども。)
「値渡し (call by value)」
「参照渡し (call by reference)」
「参照の値渡し」とか「共有渡し(call by sharing)」なる用語
Javaには参照渡しは存在しない。
(「プリミティブ型」「参照型」)
⇒これがきっかけだが、完全にわかりやすいとも言えない。
下のトラックバックやコメントも注目。

値渡しと参照渡しと参照の値渡しと - Qiita
https://qiita.com/ur_kinsk/items/949dabe975bdc1affb82
基本からまとめてくれてる。「プリミティブ型」とか。
C++JavaPythonの例。
しかし、「Pythonの説明がやや不正確だったため追加の記事を書きました」として、次の記事↓を紹介してる。

参照についてもう少し詳しく ~PythonJavaを例に~ - Qiita
https://qiita.com/mpyw/items/41230bec5c02142ae691#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%A8%E5%8F%82%E7%85%A7

値渡しと参照渡し (と参照の値渡し) - ぐるぐる〜
http://bleis-tift.hatenablog.com/entry/20090603/1244031097
最後のまとめがスッキリ!
Java, C++, C#



★ほとんどの言語で、「参照型」は、普通にやれば、「参照の値渡し」になる。
つまり、変数を丸ごと書き換えることはできるが、
変数の(オブジェクトの)中の一部の値を変更すると、参照渡しのように、呼び出し元にも影響してしまう。
配列は普通は「参照の値渡し」になるが、PHPは特殊で、配列は「参照型」(オブジェクト?)ではなく、プリミティブ型のように扱われ、中の要素を変更しても呼び出し元に影響することはない。
(⇒2018/10/24にブクマした、PHPができても他言語の学習には役に立たない理由を考えてみた。を参照のこと。


カプセル化(private)ができない?:
class - Does Python have “private” variables in classes - Stack Overflow
https://stackoverflow.com/questions/1641219/does-python-have-private-variables-in-classes

上記ページの紹介が冒頭にあるページ:
Pythonにプライベート変数を実装しようと試みた話。 - Qiita
https://qiita.com/keitakurita/items/d735e0e699719b65817a

5.9. プライベート関数 (Private Functions) - Dive into Python 5.4. (JAPANESE)
https://sites.google.com/site/diveintopythonjp/home/5-obujekuto-to-obujekuto-shikou/5-9-puraibeto-kansuu--private-functions
⇒二つのアンダースコア__で始まり、終わるものはプライベート関数、とのこと。変数はダメでも、関数は可能ってこと?

python - クラス内からしか呼び出さないメソッドを明示する方法はないでしょうか - スタック・オーバーフロー
https://ja.stackoverflow.com/questions/28172/%E3%82%AF%E3%83%A9%E3%82%B9%E5%86%85%E3%81%8B%E3%82%89%E3%81%97%E3%81%8B%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%95%E3%81%AA%E3%81%84%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%82%92%E6%98%8E%E7%A4%BA%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%AF%E3%81%AA%E3%81%84%E3%81%A7%E3%81%97%E3%82%87%E3%81%86%E3%81%8B

  • 「__ を付ける方法もありますが、不自由になりすぎるのでお勧めしません。」
  • 「_(single-underscore) や __(double-underscore) の様な internal use indicator を利用する以外に decorator と inspect を使う方法を挙げておきます。」
  • 「関数内で関数を定義することもできます。関数の外からはアクセス不可。」

Pythonのクラスメンバのスコープまとめ - Qiita
https://qiita.com/0xfffffff7/items/6ef16e79fe9886acb3f2
# プライベートクラス変数
# 外からは特別な記述でないとアクセスできない
__SecretClassVal = 10
⇒? __で終わっていないし、関数でなく、変数でもプライベート出来るの?

Why are Python's 'private' methods not actually private [python-2.7] [encapsulation] CODE Q&A Solved [English]
https://code.i-harness.com/en/q/11380
⇒実際はアクセスできる?
(/en/を/ja/に変えると日本語になるけど… 訳が変。)



■哲学、思想:

Pythonチュートリアル
リリース2.7ja1
Guido van Rossum
Fred L. Drake, Jr., editor
https://www.eidos.ic.i.u-tokyo.ac.jp/~tau/lecture/computational_physics/docs/python-doc-2.7ja1-pdf/tutorial.pdf

9.6 プライベート変数
オブジェクトの中からしかアクセス出来ない“プライベート”インスタンス変数は、Pythonにはありません。しかし、ほとんどのPythonコードが従っている慣習があります。アンダースコアで始まる名前(例えば_spam)は、(関数であれメソッドであれデータメンバであれ)非publicなAPIとして扱います。これらは、予告なく変更されるかもしれない実装の詳細として扱われるべきです。
クラスのプライベートメンバについて適切なユースケース(特にサブクラスで定義された名前との衝突を避ける場合)があるので、 マングリング(name mangling)と呼ばれる、限定されたサポート機構があります。 __spam (先頭に二個以上の下線文字、末尾に一個以下の下線文字)という形式の識別子は、 _classname__spam へとテキスト置換されるようになりました。ここで classname は、現在のクラス名から先頭の下線文字をはぎとった名前になります。このような難号化(mangle)は、識別子の文法的な位置にかかわらず行われるので、クラス定義内に現れた識別子全てに対して実行されます。
難号化の規則は主に不慮の事故を防ぐためのものだということに注意してください; 確信犯的な方法で、プライベートとされている変数にアクセスしたり変更することは依然として可能なのです。デバッガのような特殊な状況では、この仕様は便利ですらあります。

⇒「Private化できない」ということに、何が利点があるのだろう??と疑問だったが、
上記にあるようにデバックのような状況や、この項のどこかのリンク先に書いてあったが、APIなどにバグがあっても自分で修正できないと困る状況において、利点があるようだ。


コードスタイル — The Hitchhiker's Guide to Python
https://python-guideja.readthedocs.io/ja/latest/writing/style.html

どんなクライアントコードでも、オブジェクトのプロパティとメソッドをオーバーライドすることができるということです。Pythonでは “private”キーワードはありません。このような哲学は、誤用を防ぐための多くの仕組みを提供するJavaのような高度に防御的な言語とは異なり、「私たちはすべての責任あるユーザーです」と表現されています。

これは、例えばプロパティがプライベートであるとはみなされず、Pythonでは適切なカプセル化ができないことを意味しません。 Pythonコミュニティは、開発者がコードと他のコードの間に構築したコンクリートの壁に頼るのではなく、これらの要素に直接アクセスすべきではないことを示す一連の規則に頼っています。

プライベートプロパティと実装の詳細の主な慣例は、すべての “内部”にアンダースコアを付けることです。 クライアントコードがこのルールを破ってこれらのマークされた要素にアクセスする場合、コードが変更された場合に遭遇する不正行為や問題は、クライアントコードの責任です。

Pythonの思想「The Zen of Python」がとても興味深い|まえちゃんろぐ
https://blog.seiyamaeda.com/10425