Hatena::Grouppython

zorioの日記

 | 

2010-03-21

classの中と外でdefの挙動が違うのかな

23:18

インスタンスメソッドを後から他の変数に代入しても動く

# -*- encoding: utf-8 -*-
class C:
  def __init__(self, n):
    self.n = n
  
  def method(self, x):
    return self.n ** x

ins = C(2)
print ins.method(3) # => 2 ** 3 = 8

m = ins.method #ここでメソッドをmに代入
ins = C(3)
print ins.method(3) # => 3 ** 3 = 27

print m(3) # => 8

クラスの外で定義した関数をそのまま代入しても、インスタンスメソッドには出来ないみたい

# -*- encoding: utf-8 -*-
class Hoge:
  def __init__(self, n):
    self.x = n

def Method(self):
  return self.x ** 2

hoge1 = Hoge(3)
hoge1.method = Method

hoge1.method() # => 9 と動いて欲しい。
Traceback (most recent call last):

  File "C:\Users\*****\Desktop\temp.py", line 11, in C:\Users\*****\Desktop\temp.py

TypeError: Method() takes exactly 1 argument (0 given)

new.instancemethodを使えば出来るそうで。これは何をしてるんだろうな。

http://www.python.jp/doc/2.4/lib/module-new.html

参考:

http://lightson.dip.jp/zope/ZWiki/015_e7_89_b9_e7_95_b0_e3_83_a1_e3_82_bd_e3_83_83_e3_83_89

クラスに追加したら出来た

# -*- encoding: utf-8 -*-
class Hoge:
  def __init__(self, n):
    self.x = n

def Method(self):
  return self.x ** 2

hoge1 = Hoge(3)
Hoge.method = Method

print hoge1.method() # => 9
print Hoge.method(hoge1) # => 9

クラス定義の問題じゃなくて、インスタンスになにかあるんだな、きっと。

スタティックメソッドとクラスメソッド

22:30

参考:

http://jutememo.blogspot.com/2008/09/python-classmethod-staticmethod.html

スタティックメソッドの場合、メソッドを定義したクラスにしかアクセスできない

# -*- encoding: utf-8 -*-
class Base:
  isInitialized = False
  @staticmethod
  def Initialize():
    if Base.isInitialized == False:
      print "This is initialized now"
      Base.isInitialized = True
    else:
      print "This is already initialized"
    

class Derived1(Base):
  pass
  
class Derived2(Base):
  pass

Derived1().Initialize()
Derived1().Initialize()
Derived2().Initialize()
Derived2().Initialize()
実行結果:最初に作ったDerived1の時しか実行されない
This is initialized now
This is already initialized
This is already initialized ←ここが違い
This is already initialized

クラスメソッドは、実際に実行されたクラスにアクセスできる

# -*- encoding: utf-8 -*-
class Base:
  isInitialized = False

  @classmethod
  def Initialize(cls):
    if cls.isInitialized == False:
      print str(cls) + " is initialized now"
      cls.isInitialized = True
    else:
      print str(cls) + " is already initialized"

class Derived1(Base):
  pass
  
class Derived2(Base):
  pass

Derived1().Initialize()
Derived1().Initialize()
Derived2().Initialize()
Derived2().Initialize()
実行結果:最初のDerived1、最初のDerived2でそれぞれ実行される。
__main__.Derived1 is initialized now
__main__.Derived1 is already initialized
__main__.Derived2 is initialized now  ←ここが違い
__main__.Derived2 is already initialized

サブクラスでクラス変数初期化をやりたいんだけどその初期化の処理は基底クラスに書きたい、って事が実際にあったので、そういう時に便利なんじゃないかな。

PankajPankaj 2012/09/21 11:00 AFAIC that's the best aneswr so far!

afupeujpdrafupeujpdr 2012/09/21 23:46 MTalJW <a href="http://ycxcqxoejgee.com/">ycxcqxoejgee</a>

dqhbxkdqhbxk 2012/09/22 11:38 o1dD2K , [url=http://yvhtscoxhqvw.com/]yvhtscoxhqvw[/url], [link=http://ebwkccusvzdq.com/]ebwkccusvzdq[/link], http://gjkculbqdbcg.com/

ibhngctibhngct 2012/09/23 05:20 RLMPm7 <a href="http://kukgevixdgyr.com/">kukgevixdgyr</a>

egncghfcbegncghfcb 2012/09/23 17:02 9nRjzr , [url=http://maxnbuutmooq.com/]maxnbuutmooq[/url], [link=http://gienvxcvupak.com/]gienvxcvupak[/link], http://rcrbtronnqss.com/

ゲスト



トラックバック - http://python.g.hatena.ne.jp/zorio/20100321
 |