イントロ
前回のiOSエンジニアによるPython3入門(環境整備編)でmacOSにPython3の環境を整えたので、引き続き簡易的な文法の話をする
対象者
- Python初心者
- 他言語経験者 (特にSwift3以降を触ったことある人向け)
Python3のざっくりとした特徴や説明
- Pythonは動的型付き言語で、変数に対して型宣言することはない。
- Python3では文字エンコードはUTF-8がデフォルトとして固定されている
記事の概要や説明
- Swiftと対比的に記載していく
- SwiftやSwift2系でも使用できるコードもあるが、Swift3以降を基準に記載
-
Swift3orLater
とあればSwift3以降で、Swift4
とあればSwift4でのサンプルコードを表す。
文法
定数
// グローバルスコープの時
let MAX_SIZE = 44.0
let MIN_SIZE: Double = 0.0
// ローカルスコープの時
static let MAX_SIZE = 44.0
static let MIN_SIZE: Double = 0.0
Pythonでは、定数は存在しない(サポートされていない)
変数名の付け方で定数として扱うよう運用カバーしている模様
主に大文字のスネークケースで記載する
MAX_SIZE = 44.0
# MAX_SIZE = 60.0 定数をサポートしていないため値を上書きできてしまう
MIN_SIZE = 0.0
変数
// 2値
let bool1 = true // true
let bool2 = false // false
// 2進数
let bit1 = 0b0000_1010 // 10
let bit2 = 0b01_01_01_01 // 85
// 16進数
let hex1 = 0xFFFFFF // 16777215
let hex2 = 0x08_08_08 // 526344
// 整数
let integer1 = 256 // 256
let integer2: Int = -128 // -128
let integer3 = 1_000_000 // 1000000
// 小数
let double1 = 3.14 // 3.14
let double2: Double = -1.414213 // -1.414213
let double3 = 3.14_15_92 // 3.141592
Swiftと割と同じ…というかSwiftがPythonから輸入してきたと思うが、_
で桁区切りの書き方ができる。桁が多い時は_
区切り使うと可読性もあがるので個人的には好き。
# 2値
bool1 = True # True
bool2 = False # False
# 2進数
bit1 = 0b0000_1010 # 10
bit2 = 0b01_01_01_01 # 85
# 16進数
hex1 = 0xFFFFFF # 16777215
hex2 = 0x08_08_08 # 526344
# 整数
integer1 = 256 # 256
integer2 = -128 # -128
integer3 = 1_000_000 # 1000000
# 小数
double1 = 3.14 # 3.14
double2 = -1.414213 # -1.414213
double3 = 3.14_15_92 # 3.141592
文字列
let string1: String = "Hello World" // Hello World
let string2 = "Hello" + " " + "World" // Hello World
Pythonでは、”
または’
で括ることで文字列になる。(Pythonのコードを見ていると’
で括ることが多い印象)
Swift同様+
で文字列を連結させれる他、括ったものを並べても連結される。
下記のstring3がその例で、'Hello'
と’ ‘(半角スペース)
と"World"
を並べることでHello World
の文字列になっている。
可読性考えると、+
での連結が1番わかりやすいと思う。
string1 = "Hello World" # Hello World
string2 = 'Hello' + ' ' + "World" # Hello World
string3 = 'Hello' ' ' "World" # Hello World
複数行文字列
// ダブルコンパイル\nメテオリック・スリーシスターズ
let multiString1 = """
ダブルコンパイル
メテオリック・スリーシスターズ
"""
let multiString2 =
"""
ダブルコンパイル
メテオリック・スリーシスターズ
"""
Swiftでは、Swift4からサポートされた複数行文字列(multi-line-string)がPythonでも使える。というかこれも輸入されたみたい。
Swiftと異なりPythonでは、=
と同じ行に"""(または''')
がある必要がある。
# ダブルコンパイル\nメテオリック・スリーシスターズ
multiString1 = """
ダブルコンパイル
メテオリック・スリーシスターズ
"""
multiString2 = '''
ダブルコンパイル
メテオリック・スリーシスターズ
'''
コメント
// 1行コメント
/// Doc用に3つ並べた書き方することもある
/*
複数行コメント
*/
SwiftとPythonは似ているところも多いが、コメントは似つかない。
Objective-Cとかの流れから//
を使うのはSwiftとしては当然なので、#
にならなかったのは良かった。
Pythonでは、複数行コメント用の正規な方法がなく、複数行文字列を流用する。
変数に代入しないことで、コードとしては無視されるので、特にパフォーマンス等にも問題ないみたい。
(後述するが、複数行文字列の表記を流用しているため、インデント位置がおかしいとエラーになる)
# 1行コメント
"""
厳密には異なるが
複数行コメント
"""
ログ
print("hello world") // 文字列"hello world"を表示
print(someObject) // someObjectを表示
SwiftとPythonで差異はない
print("hello world") # 文字列"hello world"を表示
print('hello world') # 文字列"hello world"を表示
print(someObject) # someObjectを表示
算術演算子
let addition = 5 + 3 // 8
let subtraction = 5 - 3 // 2
let multiplication = 5 * 3 // 15
let divisionInt = 5 / 3 // 1
let divisionDouble = 5.0 / 3.0 // 1.666666666666667
let remainder = 5 % 3 // 2
let power = pow(5, 3) // 125
let square = sqrt(5) // 2.23606797749979
Pythonの冪乗は、**
でかけるのが楽で少しいいなーと思う。
addition = 5 + 3 # 8
subtraction = 5 - 3 # 2
multiplication = 5 * 3 # 15
divisionInt = 5 // 3 # 1
divisionDouble = 5 / 3 # 1.6666666666666667
remainder = 5 % 3 # 2
power = 5 ** 3 # 125
square = math.sqrt(5) # 2.23606797749979
比較演算子
>
、>=
、<
、<=
、==
、!=
これらの使用方法はSwiftとPythonで同じため省略
論理演算
let number1 = 0
let number2 = 1
let number3 = -1
let bool1 = number1 == 0 // true
let bool2 = number2 > 0 && number3 < 0 // true
let bool3 = number2 > 0 || number3 > 0 // true
let bool4 = !(number2 == 0) // true
// let bool4 = !number2 == 0 // 括弧がないとNG
Pythonでは、&&
がand
、||
がor
、!
がnot
と文字で表現されている。
ちなみにxor
は試した限りエラーになったので存在しないと思われる。
number1 = 0
number2 = 1
number3 = -1
bool1 = number1 == 0 # True
bool2 = number2 > 0 and number3 < 0 # True
bool3 = number2 > 0 or number3 > 0 # True
bool4 = not(number2 == 0) # True
# bool4 = not number2 == 0 # 括弧がなくてもOK
制御文(if)
let number = 4
if number > 0 {
// number > 0 == true
} else if number < 0 {
// number < 0 == true
} else {
// !(number > 0 == true || number < 0 == true)
}
大きな違いとして、{ }
でスコープを表すSwiftに対してPythonはインデントでスコープを表す。それ故、Pythonではインデントはかなり重要な要素だったりする。複数行文字列を使用した複数行コメントのところでも軽く触れたが、インデントでスコープを扱っているため、インデント位置がおかしいだけでエラーとなるので、気をつけたい。
また、else if
の代わりにelif
といった省略されたようなものを使用したり、制御文の末尾には:
をつけるようになっている。
number = 4
if number > 0:
# number > 0 == True
elif number < 0:
# number < 0 == True
else:
# not(number > 0 == True or number < 0 == True)
制御文(条件式)
let number5 = 1
let string5 = number5 > 0 ? "foo" : "bar" // foo
Swift等の他言語でいう三項演算子はなく、それに近い条件式というものがPythonにはある。
並び順が特殊で、真の時の値``if``条件``else``偽の時の値
で書く。
number5 = 1
string5 = 'foo' if number5 > 0 else 'bar' # foo
制御文(for)
for i in 0..<5 {} // 0,1,2,3,4
for i in 5..<10 {} // 5,6,7,8,9
for i in (1...3).reversed() {} // 3,2,1
for i in stride(from: 0, through: 10, by: 3) {} // 0,3,6,9
Swiftは...
や..<
といった直感的で範囲を指定できるところは良いが、2以上ずつカウントアップした時とかにstride(from:through:by:)
がいきなり出てきて微妙な統一感のなさが嫌だったりする。
一方で、Pythonは基本range()
で表せるのは楽かつ統一的でわかりやすくていいと思う。
for i in range(5): # 0,1,2,3,4
for i in range(5, 10): # 5,6,7,8,9
for i in reversed(range(1, 4)): # 3,2,1
for i in range(0, 10, 3): # 0,3,6,9