14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Python2.7で class C: と class C(object): の違いに大ハマりした話

Last updated at Posted at 2018-02-10

旧スタイルのクラス定義というものを知っていますか

Python2 系では、class C:class C(object): が異なる挙動をするということを知らずに、大ハマりしました。

参考:

旧スタイルのクラスの違い

class C:class C(): のように、object からの継承を省略すると、Python 2.1 以前と互換の旧スタイルのクラスとなります。

>>> class OldStyle:
...   pass
... 
>>> old = OldStyle()
>>> type(old)
<type 'instance'>
>>> dir(old)
['__doc__', '__module__']
>>> class NewStyle(object):
...   pass
... 
>>> new = NewStyle()
>>> type(new)
<class '__main__.NewStyle'>
>>> dir(new)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

旧形式は instance 型、新形式は、object から派生する class 階層下という違いなのですが、私がハマったのは、旧形式では、さりげなくデコレータが動かないこと。

@property の setter が動かない

class NewStyleClass(object):
  def __init__(self):
    self._v = 0

  @property
  def v(self):
    print "get"
    return self._v

  @v.setter
  def v(self, value):
    print "set"
    self._v = value

class OldStyleClass:
  def __init__(self):
    self._v = 0

  @property
  def v(self):
    print "get"
    return self._v

  @v.setter
  def v(self, value):
    print "set"
    self._v = value
>>> new = NewStyleClass()
>>> new.v
get
0
>>> new.v = 100
set
>>> new.v
get
100
>>> old = OldStyleClass()
>>> old.v
get
0
>>> old.v = 100 # ← setter が呼ばれていない
>>> old.v       # ← 上書きされて getter が行方不明に
100

中途半端に getter が動いている分、たちが悪いです。。。

Python3 では新形式に統一

Python3 では、両方の書き方で新形式の振る舞いになりますので、安心です。

しかし、それ故に、Python3 向けのコードでは class C: 形式で書かれているため、望ましい書き方はそっちなのかと勘違いし、Python 2.7 向けのコードをリファクタリングして動かなくなるという悲劇が。

結論

Python2.7 では class を書くときには object を明示的に継承しましょう。

14
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?