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

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

ただいまの
回答率

88.81%

クラスの書き換えとオーバーライドは同じか?

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 838

blendegg

score 54

疑問

クラスを継承したあとで、書き換える方法がわからないので教えてください。
さがしてみたんですが、初心者に理解できるものが見つからなかったです。

コード

class classname():
    a = 10
    def func():
        print(a)

class myclass(classname):
    classname.a = 100
    classname.func()

質問です

1:変数aの値を書き換える方法を教えてください。また、クラスの内容を書き換えることをオーバーライドと呼ぶのでしょうか?

2:変数aを100に書き換えたいというコードですが、4行目のaが定義されていないというエラーが出るようです。selfが関係しているでしょうか?
しかし、func関数からしたらグローバル変数なのだから、アクセスできるはずですが、、、
なかなか素人にもわかるような解説サイトがないので、質問させてもらいます。

補足

ごめんなさい治しました(´・ω・`)

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • y_waiwai

    2019/05/08 10:18

    このままではコードが見れないので、質門を編集し、<code>ボタンで、出てくる’’’の枠の中にコードを貼り付けてください

    キャンセル

  • BeatStar

    2019/05/08 10:39 編集

    コードは質問や修正時の"<コード>" だった気がしますが、それを使って書いてください。
    Pythonはインデントが物を言いますよね?
    意味が相当変わってくるので、ちゃんと修正してください。
    ※ "<code>" になっているようです。

    キャンセル

  • hayataka2049

    2019/05/08 13:04

    前にも書きましたが、サイトを見てわからなかったのであれば「このサイトの記述のこの部分がわからない」という質問を立てて頂いたほうが良いと思います。このサイトの性質上、初心者向けの解説サイトに詳しい回答者は少ないですし、何回「わからない」と言われても「どうすればわかってもらえるのかわからない」という感想を抱かれてしまいがちです。現時点でわかっている点、わからない点を自分でまとめて、何がわかれば理解できると思うのかを示した方が的確なアドバイスが得られます。

    キャンセル

回答 2

checkベストアンサー

+2

1:変数aの値を書き換える方法を教えてください。また、クラスの内容を書き換えることをオーバーライドと呼ぶのでしょうか?

質問文の例はおそらく意図している動作とは違いますし、オーバーライド「ではない」と言えます。

理由1

classname.a = 100だと親クラスのクラス変数aを変更してしまうからです。これでは親クラスに影響が及んでしまいます。

class Hoge:
    a = 10

というクラスがあったとして、

class Fuga(Hoge):
    a = 20

とすれば、親クラスHogeには影響を及ぼさずにFuga.aだけ20にすることができます。こういうことを意図しているのだと思います。

理由2

そもそもオーバーライドという言葉は、メソッドに対して使われるのが一般的です。クラス変数で同等のことをするのはオーバーライドとはあまり言わないと思います。

オブジェクト指向プログラミングにおいてオーバーライド (override) とは、スーパークラスで定義されたメソッドをサブクラスで定義し直し、動作を上書き(変更)することである。
オーバーライド - Wikipedia

2:変数aを100に書き換えたいというコードですが、4行目のaが定義されていないというエラーが出るようです。selfが関係しているでしょうか?

あまり知られていないのですが、クラスのスコープは特殊な仕様になっており、クラス定義内に作られた変数は下位スコープから参照できません。

クラス定義ブロックと exec() や eval() に対する引数は、名前解決の文脈で特別です。クラス定義は、名前を使うことと定義することができる実行可能な文です。これらの参照は、名前解決のための通常のルールに従いますが、束縛されていないローカル変数がグローバルな名前空間から検索されるという例外があります。クラス定義の名前空間はクラスの属性辞書になります。クラス内で定義された名前のスコープは、クラスのブロックに限定されます; メソッドのコードブロックには拡張されません。

https://docs.python.org/ja/3/reference/executionmodel.html#resolution-of-names

クラス変数にアクセスする場合は、クラス名.クラス変数名を使ってください。


また、定義されているメソッドにself引数がないのも変ですね(前にも書いたので繰り返しません)。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/08 18:06

    回答ありがとうございました
    クラス変数にアクセスするにはselfが必要ということですね

    書き換え方法についても理解できました

    キャンセル

  • 2019/05/08 23:31

    >クラス変数にアクセスするにはselfが必要ということですね
    違います。selfが「絶対に」必要になるのはインスタンス変数の場合です。クラス変数にはselfに関係なくClassName.VariableNameでアクセス可能です。が、そもそも普通のメソッドの書式としてselfを引数に取るということが決まっているので、おかしいというだけです。

    キャンセル

0

さがしてみたんですが、初心者に理解できるものが見つからなかったです。

本当に探しましたか?

そもそも、名称も変ですし、入門書に乗っているレベルです。
( 現に、悪名高いC言語やC++ですら、載っています。 )

変数 a はグローバル変数なのでしょうか? それともフィールド? そもそもクラスの書き方自体がおかしいです。 言語によって書き方が変わりますが、

(URL先には関係がないため削除)

を見ると、クラス内に直接書いているものがありません

変数aの値を書き換える方法を教えてください。また、クラスの内容を書き換えることをオーバーライドと呼ぶのでしょうか?

本当に探しましたか?

「オーバーライド とは」で検索するとわかりそうでわからないがヒット。

クラスの内容っていうより、メソッドの動きを変えること。

例えばClass1 があり、これは runメソッドを持っているとします。

で、Class1のrunメソッドは "ファイル名を変更する"処理だとします。

これを継承して Class2 を定義。

このClass2のrunを書き換えて、"フォルダ名を変更する" のと、"ファイルを生成する" という処理にする。

すると、Class1で生成されたなら、"ファイル名の変更",
Class2で生成されたなら、"フォルダ名変更"および"ファイル生成"
となる。( runメソッドの動きね。)

この動きの変更のこと。

これはOOPがわからなくても入門書読めばわかると思うんだけど...

2は前述したとおりです。 そもそも書く場所が違う。
メソッドを用意して、それで書き換えるか、 コンストラクタに相当するinit ? で書き換える。


[追記1]

hayataka2049さんからご指摘を受けました。

上の一部を削除しました。

(恥ずかしい...orz...)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/08 12:56

    >そもそも書く場所が違う。
    a = 10に関しては、問題ない書き方ですよ
    __init__内でselfの属性に対して代入すればインスタンス変数に、クラス定義内に直接書いた場合はクラス変数として取り扱われます。
    https://docs.python.org/ja/3/tutorial/classes.html#class-objects

    キャンセル

  • 2019/05/08 13:18

    hayataka2049さん。

    そうなんですか!?
    失礼いたしました...
    修正します...

    キャンセル

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

  • ただいまの回答率 88.81%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る