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
メソッドを呼び出しています。
呼び出した時点でfoo
は45
になっているので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
メソッドを呼び出しています。
呼び出した時点でfoo
は45
になっているので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のクラスメソッドとインスタンスメソッドについて補足します。
(続く...)
