RubyプログラマがPythonを学び始めて知ったこと10選 ④

1 クラスのメソッド定義の第一引数には必ずselfが必要。

class MyClass:
  def my_method(self):
    # 処理

尚、第一引数の名前は別にselfでなくてもよい。ただ慣習的にselfが使われる。

2 クラスをインスタンス化するには関数表記を使う。

class MyClass:
  def my_method(self):
    return 1


m = MyClass() # インスタンス化
m.my_method()
=> 1

ちなみにメソッドコールの時はselfは不要。暗黙的に現在のオブジェクトが渡される。

3 クラス名の一文字目は小文字でもよい。

よいけど、慣習的に大文字にしてるのだとか

class my_class:
  def my_method(self):
    return 1


m = my_class()
m.my_method()
=> 1

ちなみにモジュール名も小文字でよい。よいどころか小文字が一般的のようだ。

4 関数の中から関数外の変数へのアクセスはリードオンリー。

a = 10
def r():
  return a # 読み込みの時は関数外の変数が参照される。

def w():
  a = 1 # 書き込みの時は関数外とは別のローカル変数が生成される。
  return a

r()
=> 10

w()
=> 1

a
=> 10

5 メソッドの中からクラスのデータメンバ(変数)を参照する場合、レシーバを省略できない。

class MyClass:
  i = 0 # データメンバ
  def my_method(self):
    return i # レシーバ(self)がないのでエラーになる

先の「4 関数の中から関数外の変数へのアクセスはリードオンリー」の例は関数の例であるためレシーバ無しでも上手くいくがメソッドの場合はレシーバが必要。

6 データメンバ(変数)はJavaScriptのようにクラス外部から手軽に定義できる。

class MyClass:
  pass

m = MyClass()
m.my_variable = 1
m.my_variable
=> 1

7 __str__()メソッドという特殊メソッドがある。

これはRubyのinspectメソッドのようにオブジェクトの内部を人間にわかりやすく表示するためのもの。

class MyClass:
  def __str__(self):
    return 'foo'


m = MyClass()
print(m)
=> foo

Rubyのpメソッドがオブジェクトのinspectメソッドを利用するようにPythonではprint()関数がオブジェクトの__str__()メソッドを利用する。

8 JavaScriptのようにメンバ変数・メソッドの名前でアクセス制御する。

つまり、それが慣習であって、厳格に非公開にすることはできない。

class MyClass:
  # public変数
 public_variable = "public variable"
  
  # publicメソッド
  def public_method(self):
    return "public method"

  # private変数(頭にアンダースコアを付ける)
  _private_variable = "private variable" 

  # privateメソッド(頭にアンダースコアを付ける)
  def _private_method(self):
    return "private method"


m = MyClass()
m.public_variable
=> 'public variable'

m.public_method()
=> 'public method'

m._private_variable   # 慣習なので、その気になればアクセスできる
=> 'private variable'

m._private_method()   # 慣習なので、その気になればアクセスできる
=> 'private method'

尚、頭にアンダースコアを2つ続けると、慣習ではなく本当にその変数やメソッドにアクセスできなくなるが、これも完全に非公開になったわけではなく、ある法則によって別名に変換され、元々の名前ではアクセスできなくなっただけ。

class MyClass:
  def __private_method(self):
    pass


m = MyClass()
m.__private_method()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute '__my_func'

Rubyでいうprotectedは言及されていないのでPythonには無いのかも知れない。

9 Rubyと同じく定数は変数名を大文字で表す。

ただし、Pythonでは変数名の全ての文字を大文字にする。それが慣習。つまりプログラマが定数として扱うだけであって本質的には通常の変数となんら変わりない。

CONSTANT = 'constant variable'
CONSTANT
=> 'constant variable'

CONSTANT = 'foo' # 変更しても何も怒られない
CONSTANT
=> 'foo'

10 Rubyと同じく++, --がない。

a = 0
a++
  File "<stdin>", line 1
    a++
      ^
SyntaxError: invalid syntax