情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

Pythonのクラス(2)

前回、「インスタンスメンバでクラスメンバを隠してしまうことが出来る」と書きました。

クラスメンバというのは、一般に静的なメンバのことです。

★ActionScript3.0

public static function show_foo() : void
{
}

★C#/Java

public static void show_foo()
{
}

★VB

Public Shared Sub show_foo()
End Sub

では、「インスタンスメンバでクラスメンバを隠してしまうことが出来る」とはどういうことでしょうか?

今回は、JavaScriptとPythonのクラスを比較することでPythonのクラスについて更に深く観察してみます。

まずは、JavaScriptから。下のようなクラスを考えます。

function MyClass()
{
    this.foo = 23;
    this.show_foo = function()
    {
        alert(this.foo);
    };
}

起。

var a = new MyClass();
a.show_foo();

インスタンス化してshow_fooメソッドを呼び出しています。

当然ながら23が表示されます。

承。

var b = new MyClass();
b.foo = 45;
b.show_foo();

インスタンス化してfooの値を45に変更した後show_fooメソッドを呼び出しています。

呼び出した時点でfoo45になっているので45が表示されます。

転。

var c = new MyClass();
c.show_foo();
alert(MyClass.foo);
MyClass.foo = 67;

最初に、新たなインスタンスcを作って、インスタンスbからのfoo値の変更がMyClass自体のfooに影響していないことを確認します。

23と表示され影響が無いことが分かります。

次に、MyClassで定義されたfooへの直接参照と値の変更を試みてみます。

undefinedと表示されました。JavaScriptではMyClassからの直接アクセスは出来ないようです。

結。

var d = new MyClass();
d.show_foo();

もう一度インスタンス化してshow_fooメソッドを呼び出してみます。

23と表示されます。結局、上で行ったMyClassへの直接的な代入は何の効力も無かったことが分かりました。

次にPythonに全く同じ処理をさせてみます。

下のようなクラスを考えます。

class MyClass():

  foo = 23

  def show_foo(self):

    print self.foo

起。

a = MyClass()
a.show_foo()

インスタンス化してshow_fooメソッドを呼び出しています。

当然ながら23が表示されます。

承。

b = MyClass()
b.foo = 45
b.show_foo()

インスタンス化してfooの値を45に変更した後show_fooメソッドを呼び出しています。

呼び出した時点でfoo45になっているので45が表示されます。

転。

c = MyClass()
c.show_foo()
print MyClass.foo
MyClass.foo = 67

最初に、新たなインスタンスcを作って、インスタンスbからのfoo値の変更がMyClass自体のfooに影響していないことを確認します。

23と表示され影響が無いことが分かります。

次に、MyClassで定義されたfooへの直接参照と値の変更を試みてみます。

23と表示されました。PythonではMyClassからの直接アクセスが可能なようです。

結。

d = MyClass()
d.show_foo()
a.show_foo()
b.show_foo()

もう一度インスタンス化してshow_fooメソッドを呼び出してみます。

67と表示されます。結局、上で行ったMyClassへの直接的な代入が反映されていることが分かります。

試しに、aインスタンスからもshow_fooメソッドを呼び出してみます。67と出力されます。こちらも変更が反映されています。

最後に、bインスタンスからもshow_fooメソッドを呼び出してみます。対照的に45と表示されます。こちらは変更が反映されていません。

上の実験から次のことが考察出来ます。

・JavaScriptではインスタンスからしかメンバにアクセス出来ない。
 →Javascriptのクラス内で定義されたメンバは常にインスタンスメンバになる。
・Pythonでは、<クラス名>.<メンバ名>の形でも<インスタンス名>.<メンバ名>の形でもメンバにアクセスすることが出来る。
 →Pythonのクラス内で定義されたメンバはクラスメンバかつインスタンスメンバ?
・インスタンスからメンバの内容を変更した場合、大本のクラスの方には変更が反映されていない。
 →クラスメンバとインスタンスメンバは別物。
・クラスからメンバの内容を変更した場合でも、その前にインスタンスからメンバの内容を変更してあると、そのインスタンスからメンバにアクセスしても変更が反映されていない。
 →クラスメンバとインスタンスメンバは別物で、インスタンスメンバの方が優先される(下位スコープ)。但し、インスタンスメンバが定義されていない時にインスタンスからメンバにアクセスしようとすると、インスタンスメンバの代わりにクラスメンバにアクセスされる(当該スコープに存在しなかったので上位に探しに行った)。

次回は、Pythonのクラスメソッドとインスタンスメソッドについて補足します。

(続く...)

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-python