Python 使いのための、Python と Ruby の違い(基本文法)
こんにちは。吉田弁二郎です。
今回は、web 開発の主力言語の一つとなっている Ruby の文法について、Python との違いをまとめます。文法の完全な紹介を目指すのではなく、特に紛らわしい項目の差分に注目していきます。そのため、Ruby 独自の文法的な事項(module/include/extend, Proc など)には触れていませんのでご容赦を。なお、今回は Python 3.5.2 および Ruby 2.3.1 で確認しています。
制御構文
範囲の記述(1から5まで)
# Python range(1, 6)
# Ruby:以下はいずれも同じ 1..5 1...6 1.upto(5)
偽と判定されるもの
# Python None False [] # 空の配列 '' # 空の文字列 0
# Ruby nil false
ループ中、次の繰り返しに移動する方法
# Python:continue キーワードを使う sum_even = 0 for i in range(10): if i % 2 == 0: continue # <- else: sum_even += 1
# Ruby:next キーワードを使う sum_even = 0 (0...10).each do |i| if i % 2 == 0 next # <- else sum_even += 1 end end
ハッシュに対する for 文
# Python:キーを取り出す h = {'hoge': 1, 'foo': 2} res = [] for item in h: res.append(item) #=> res = ['hoge', 'foo']
# Ruby:キーと値の組を取り出す h = { hoge: 1, foo: 2 } for item in h res.push item end #=> res = [[:hoge, 1], [:foo, 2]]
Python で Ruby のこの for 文と同様のことをする場合は
for item in h.items(): res.append(item)
となります。Ruby の方は見づらいので
h.each do |key, value| ... end
とした方がよい気がします。
ワンライナー条件文
# Python: a = 1 'one' if a == 1 else 'not one' #=> 'one'
# Ruby: a = 1 a == 1 ? 'one' : 'not one' #=> 'one'
例外処理
# Python: from sys import exc_info a = 1 try: a.hoge # エラー送出 except Exception as e: info = exc_info() print("error class: {}".format(info[0])) print("error message: {}".format(info[1])) finally: print('done.')
# Ruby: a = 1 begin a.hoge # エラー送出 rescue => e puts e.class puts e.message ensure puts 'done' end
配列
インデックス参照
# Python:範囲外のインデックス参照はエラーとなる a = [0, 1] a[2] #=> IndexError
# Ruby:範囲外のインデックス参照は nil を返す a = [0, 1] a[2] #=> nil
これはハッシュでも同様です。Ruby は寛容ですね。
文字列
文字列への変数の挿入
# Python:format 関数を使う lang_name = 'python' "hello {name}!".format(name=lang_name) #=> "hello python!"
# Ruby: lang_name = 'ruby' "hello #{lang_name}!" #=> "hello ruby!"
文字列表示のための関数
# Python print('hoge!')
# Ruby puts 'hoge!' # 文末に改行がつく。Python の print と同様 print 'hoge!' # 文末に改行がつかない
関数
可変長引数
# Python def func(*args): print(args) a = [1, 2, 3] func(a) #=> ([1, 2, 3], ) func(*a) #=> (1, 2, 3)
# Ruby def func(*args) print args end a = [1, 2, 3] func(a) #=> [[1, 2, 3]] func(*a) #=> [1, 2, 3]
Python ではタプルが、Ruby では配列が返る以外は同じ挙動ですね。func(*a) の * は配列を引数展開して渡すことを表します。
可変長キーワード引数
# Python def func(a=0, b=0): print("a is {}, b is {}".format(a, b)) func() #=> a is 0, b is 0 func({"a": 1, "b": 2}) #=> a is {"a": 1, "b": 2}, b is 0 func(**{"a": 1, "b": 2}) #=> a is 1, b is 2
# Ruby:引数の波括弧を省略可能 def func(a: 0, b: 0): puts "a is #{a}, b is #{b}" end func() #=> a is 0, b is 0 func("a": 1, "b": 2) #=> a is 1, b is 2 func(**{"a": 1, "b": 2}) #=> a is 1, b is 2
クラス
宣言(継承しない場合)
# Python class Klass(object): ...
# Ruby class Klass ... end
初期化メソッドとインスタンス化
# Python class Klass(object): def __init__(self, *args, **kwargs): .... klass = Klass(*args, **kwargs)
# Ruby class Klass def initialize(*args, **kwargs) ... end ... end klass = Klass.new(*args, **kwargs)
クラス内でのインスタンス変数の表現
# Python
self.var
# Ruby @var
クラスメソッドの定義
# Python class Klass(object): ... @classmethod # デコレータ def hoge(cls): # cls を引数に取る ...
# Ruby class Klass ... def self.hoge ... end end
変数・メソッドの隠蔽
Python | Ruby |
---|---|
・通常は隠蔽されていない ・ _, __ を変数名・メソッド名の頭につけると隠蔽される |
・通常は隠蔽されている ・インスタンス変数:アクセスメソッドを設定すれば隠蔽が解除される(attr_accessor 等) ・メソッド:private / protected / public の設定により隠蔽レベルを制御できる |
その他
コメント
# Python:これが1行コメント """ これは複数行コメント。空白・改行が反映される。 """
# Ruby:これが1行コメント =begin これが複数行コメント。= の前に空白があると機能しない。 ヒアドキュメントについては割愛。 =end
外部ファイル(ライブラリ)の読み込み
# Python import hoge from hoge import foo # hoge から foo だけを読み込み
# Ruby require 'hoge' # hoge で定義されたローカル変数以外を全て読み込み
「モジュール」という名称
Python | Ruby |
---|---|
・コードをまとめた .py ファイルのこと ・「モジュールを import する」等 |
・module で定義されるコード片のこと ・「モジュールを include する」等 |
参考:
- 作者: 高橋征義,後藤裕蔵,まつもとゆきひろ
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2016/02/26
- メディア: 単行本
- この商品を含むブログ (1件) を見る
- 作者: Mark Lutz,夏目大
- 出版社/メーカー: オライリージャパン
- 発売日: 2009/02/26
- メディア: 大型本
- 購入: 12人 クリック: 423回
- この商品を含むブログ (133件) を見る