こんばんは。
pythonを勉強し始めましたが理解できない部分があって質問させて頂きます。
プログラム、特にオブジェクト指向をまだよく理解していないのである程度初心者向けの回答をお願いします。
pythonにおいて文字列はオブジェクトであり、
>>> strA = "python"
>>> print (strA)
python
>>> print (strA.upper())
PYTHON
>>> print (strA)
python
のように使われるメゾッドが存在しています。
これはオブジェクト自体を変化させるのではなく、今回の場合ではオブジェクトがupper()されたオブジェクトを返しています(まちがっていませんよね?)。
そのため、strA自体を変化させるには
>>> strA = strA.upper()
>>> print (strA)
PYTHON
のようにする必要があると理解していました。
ここで新しいオブジェクトlistを用いた時
>>> tl = ['A','B','C','D','E','F']
>>> print (tl)
['A', 'B', 'C', 'D', 'E', 'F']
>>> print(tl.reverse())
None
>>> print(tl)
['F', 'E', 'D', 'C', 'B', 'A']
>>> listA.reverse()
となります。文字列から類推すると
>>>tl = ['A','B','C','D','E','F']
>>>print (tl.reserve())
['F', 'E', 'D', 'C', 'B', 'A']
>>>print(tl)
['A','B','C','D','E','F']
>>>tl =tl.reserve()
>>>print (tl)
['F', 'E', 'D', 'C', 'B', 'A']
のような振る舞い方を行うのが"正しい"と思うのですがなぜ違うのでしょうか?
No.3ベストアンサー
- 回答日時:
Pythonのリファレンスマニュアルより
5. 組み込み型
http://docs.python.jp/2.7/library/stdtypes.html
5.6.4. 変更可能なシーケンス型
http://docs.python.jp/2.7/library/stdtypes.html# …
注釈 7
> sort() および reverse() メソッドは大きなリストを並べ替えたり反転したりする際、容量の節約のためにリストを直接変更します。副作用があることをユーザに思い出させるために、これらの操作は並べ替えまたは反転されたリストを返しません。
sort,reverseについては、このように説明があります。
変更不可(immutable)なオブジェクトに対しての、破壊的メソッドはありません。破壊的であるならば、それは「変更可能」ということを意味するからからです。
同様に、変更可能(mutable)なオブジェクトには、破壊的メソッドが存在します。そうでなれば、変更可能である意味が無いからです。
やり方に正解も不正解もありません。
Pythonの設計者達は、この方法がいいと思ったから、この方法を採択したのでしょう。
No.7
- 回答日時:
回答No.6へ
今どき、JavaScriptでも文字列は不変で、配列は可変なので、ある意味軽量言語界ではこの区別は常識という感じです。
それで困った事がないので、問題ないのだと思います。
感覚的には、不変な型のほうが相対的に少ないので、すぐ気づく感じでしょうか。
なお、Pythonにおいて自作クラスを不変な型にするのは、一手間あった記憶があります。なにもせず放っておくと勝手に可変な型という扱いになる感じです。(破壊的メソッドがなくとも)
とはいえ、自作クラスを不変な型にするメリットは、辞書のキーに使えるぐらいしか無いので、あまりしたいとは思いません。
No.6
- 回答日時:
ごめんなさい。
回答ではないのですが、面白かったのでコメントします。メソッドに定数的なものと変数的なものがあるのは便利そうですね。
ただ、その使用に際して明確な違いがないとコードを見た際にそのメソッドが
どうゆう挙動をするのかが直感的に解りにくいのはデバッグの時などに、特に
言語に馴染んでない場合など苦労しそうです。
現状では、メソッドを変数に代入する際に変数名で差別化するのが賢明な
対処なのでしょうが、出来れば言語レベルでの明確な差別化が欲しいところですね。
プログラムの学習頑張ってください。
No.5
- 回答日時:
No.4にもうちょい追加で。
pythonの組み込み型では一般的に、可変なオブジェクトがあったとき
オブジェクト.sort() はオブジェクトが変わる
オブジェクト.reverse() はオブジェクトが変わる
だけど
sorted(オブジェクト) はオブジェクトは変わらない(新規に生成される)
reversed(オブジェクト) はオブジェクトは変わらない(新規に生成される)
となるみたい。
なお、不変な型は何をしてもオブジェクトは変わらない。
No.4
- 回答日時:
> >>> strA = "python"
> そのため、strA自体を変化させるには
>
> >>> strA = strA.upper()
> >>> print (strA)
> PYTHON
>
> のようにする必要があると理解していました。
これは、strA自体を変化させるというよりは・・・
strA ---> "python"
の状態から、
"python" ===オブジェクトを新規生成===> "PYTHON"
そして
strA --x リンクを外す x--> "python"
からの
"PYTHON" <--- 新たにリンク付け--- strA
という感じ。文字列は『不変』でしょ?
(変数とオブジェクトのリンクが変わっただけ)
不変なもの: 数値、文字列、タプル
可変なもの: リスト、その他ほとんどのクラスのオブジェクト
実際、Pythonの哲学として、「規約なんてどうせすぐ破られる」というのが有るのではないでしょうか。
だからRubyのように、「末尾に ! がついてるメソッドを呼ぶと壊れる、かもね(※)」みたいな中途半端なお約束は一切せずに、
型として不変/可変を決めておいて、不変な型であれば絶対変わりませんよ(ここはRubyなども同じ)。あとは可変なオブジェクトのメソッドが破壊的であるかどうかは、それぞれ個々のマニュアルを読んでね(面倒だけど、始めから守れないと分かりきってるルールを決めるよりマシ)。というスタンスなのです。
だからかどうか知りませんが、PythonではRubyと違い、文字列は不変ですし、不変なリストとしてタプルがあります。
不変な型が多めなので、あまり困った事はありません。変えたくなければ不変な型を使えばいいのです。
文字列が不変であることで、不便な場合もありますが、反面、変わらない安心感があります。
私は安心感が有る方がいいです。(Rubyでは不変な文字列としてシンボルを用意しましたが、だったら文字列が不変でいいじゃないかと・・・)
※:実際、ruby on railsなどでも、守られていない場合が結構ある。
No.1
- 回答日時:
まず、まだ初心者なんだから下手な類推をするよりも、マニュアルや入門書、入門サイトを読んで勉強しましょう。
このハナシは、オブジェクト指向とはあまり関係がありません。
どちらかといえば、関数型プログラミングに関係が深いハナシです。
メソッドは、オブジェクトの中身を変更するものとしないものの2つに分けられます。
前者を「破壊型」、後者を「非破壊型」といいます。
最初の例のstr.upperは、あなたの理解どおり、strオブジェクトの内容を変更しない、非破壊型です。
これに対して、list.reverseは、listの内容を変更(並び準が逆になってしまう)する破壊型のメソッドです。
str.upperメソッドの方は、非破壊型であり、strオブジェクトの値を変更できないのですから、
大文字に変更した結果の文字列を新たに生成して、戻り値として返します。
一方、list.reverseの実行結果は、list自体に残されているため、戻り値として返す必要がありません。
だから、戻り値がNoneで何の不都合もありません。
変更後のlist自体を戻り値として返すこともできますが、そうすると、str.upperのように、新たなオブジェクトを
生成しているようにも見え、かえって誤解を招く動作とも言えます。
ですから、ある程度、勉強した人は、この動作の方が「正しい」と感じるようになります。
ちなみに、strオブジェクトはimmutableと言われます。その値を変更できない、ということです。
>>> strA = strA.upper()
という処理の実行前と実行後では、変数strAが指すオブジェクトが違うオブジェクトを指しているのであり、
strAが指すオブジェクトの中身が変わったのではありません。ここの違いを理解することは大切です。
>
str.upperメソッドの方は、非破壊型であり、strオブジェクトの値を変更できないのですから、
大文字に変更した結果の文字列を新たに生成して、戻り値として返します。
一方、list.reverseの実行結果は、list自体に残されているため、戻り値として返す必要がありません。
だから、戻り値がNoneで何の不都合もありません。
変更後のlist自体を戻り値として返すこともできますが、そうすると、str.upperのように、新たなオブジェクトを
生成しているようにも見え、かえって誤解を招く動作とも言えます。
はい、この部分は理解しています。
僕がわからないのは、あなたが新しく教えてくださった語句によるところの
破壊的メゾッドと非破壊的メゾッドが混在しているのはなぜか、という部分です。
どちらかに統一する方が簡単ではないかと思ったからです。
str型がimmutableであり、list型はimmutableではないこと、つまり
immutableなものに対しては非破壊的メゾッド、immutable出ないものに対しては破壊的メゾッドが備わっていると解釈すべきですか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBA エンターキーでイベントに...
-
エクセルVBAでセル番地を指定し...
-
ユーザーフォームのインポート...
-
Excel2007 でのチェックボック...
-
LoadImage関数について(VC++)
-
VBAでフォームのコントロールの...
-
VB6にて文字型変数の内容をオブ...
-
ACCESSマクロ、Me![氏名] その...
-
VBA:ホームページ内のデータテ...
-
pythonのメゾッドの整合性について
-
アクセスで説明の欄の隠しオブ...
-
「PC Helpsoft Driver Updated...
-
findは動くがfindnextがマクロ...
-
メルカリのメルカードで買い物...
-
エクセルVBAで、MsgBox やInput...
-
「ご処理進めて頂きますようお...
-
生活保護受給者は性欲をどんな...
-
UPS警告音を止めたい
-
お家デートをしててハグを長い...
-
EXCEL VBA マクロ 実行する度に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA エンターキーでイベントに...
-
アクセスVBAのMe!と[ ]
-
【エクセルのマクロ】クリップ...
-
Accessのフォーム上にエクセル...
-
Excel VBAでマウスの左クリック...
-
文字列で小数点以下の0を削除し...
-
現在アクティブになっているオ...
-
日本語の文字化けを直す方法
-
エクセルVBAでセル番地を指定し...
-
【エクセル】複数のTextBoxに共...
-
ユーザーフォームのインポート...
-
VBAでフォームのコントロールの...
-
コードでオブジェクトを最前面に
-
ExcelのシートをAccessで表示し...
-
Access からオブジェクトとして...
-
PowerpointVBAで指定のShapeオ...
-
「SHDocVw」の意味
-
Excel2007 でのチェックボック...
-
サブルーチンにオブジェクト名...
-
txtNo,txtDate等の意味
おすすめ情報