🐍

JavaScript開発者のためのPython入門

2021/06/15に公開

はじめに

ここのところ普段はJavaScript(TypeScript含む)メインで開発しています。
最近Pythonのコードを読むことが増えてきたので、なんとなく読んでるを卒業しようかと基礎をいったん学んでみることにしました。

結果、JavaScriptで見た目が違うだけでプログラミング言語の中でもだいたい書き味は似たような感じだな。という印象を受けました。(前回新しく学んだスクリプト言語がRubyだったからというのもある)
そこで、こういうところがJSと違うというところだけ抑えておけばあとは普通になんとなく書けるのではないかなということを思いまして差分をまとめてみました。

自分の備忘録と私と似たようなケースの人に読んでいただければ嬉しいです!

前提

JavaScriptはES6
Pythonは3です。(Pythonのバージョンの違いでどう違うのかとかは全く知らない)

基本文法

Hello World

何はともあれこれです。

  • JavaScript
console.log("Hello World!");
  • Python
print("Hello world!")

JavaScriptと同じように複数出力したり、

print("hello","world!")

以下の一例のように、変数をフォーマットに当てることもできます。

print("Hello world, %s !" % (name))

拡張子

何を今更ですが、JavaScriptは.jsでPythonはpyです。
読み方はずっと「パイ」だと思っていたんですが、実際のところ皆さんどっちなんでしょう・・・?

文末・コメント

Pythonは文末セミコロンはありません。
JavaScriptはどちらでも行けますが、私はセミコロンつけるタイプです。
コメントの書き方は異なりますが、基本VSCodeのショートカットでコメントアウトしてるのであんまり気にしたことありません。

  • JavaScript
// 1行のコメント
/* 
複数行コメントはこんな感じです。
複数行コメントはこんな感じです。
*/
var a = 5;
var a = 5
  • Python
# 1行のコメント
"""
複数行コメントはこんな感じです。
シングルクオーテーションまたはダブルクオテーション3つで開始/終了ですが、手書きするときはあんまり使わなかったですねそう言えば・・・
"""
x = 5

変数宣言

JavaScriptもPythonもデータ型はつけなくても大丈夫です。
JavaScriptにおいては変数の前にletconstをつける必要がありますね。(あともうほぼ使わないvar・・・)

  • JavaScript
let str = "Variable declaration";
  • Python
str = "Variable declaration";

なお、Pythonには定数宣言(JavaScriptで言うconst)はありません。
ただ、通例として大文字とアンダースコアで書くことが多いようです。

  • JavaScript
const constantStr = "CONSTANT Variable";
  • Python
CONSTANT_STR = "CONSTANT Variable";

ブロック

変数やif文などで多用するブロックの表現は、Pythonの場合インデントで表現します。
正直ここさえ知っていればもういいんじゃないかと思っています。

  • JavaScript
// 関数
function fn () {
  // 関数ブロック
  let a = 5;
}
// ブロック外なのでaは使えません
// console.log(a);

{
  // 囲っただけのブロック
  x = 10;
}
  • Python
# 関数
def fn():
    # 関数ブロック
    a = 5

# ブロック外なのでaは使えません
# print(a)

    # 囲っただけのブロック
    x = 10
    

データ型

Primitive

基本的には似たように扱えます。数値型に関してはJavaScriptはざっくりNumber(大きいものはbuild inでBigIntがありますね)ですが、Pythonはfloatintです。

  • JavaScript
const number = 4; // number
const pi = 3.14; // This is also number
const str = "Hello world!"; // String
const bool = true; // Boolean
  • Python
number = 4; # number
pi = 3.14; # This is also number
str = "Hello world!"; # String
bool = True; # Boolean(trueとかTUREだとダメ)

なお、型チェックと型変換はこんな感じです。

  • JavaScript
console.log(typeof pi);  // number
console.log(Number.parseInt(pi))  // 3
  • Python
print(type(pi))  # float
print(int(pi))  # 3(元は3.14)

配列

JavaScriptではArray, PythonではListsと呼ばれます。
大体同じですが、文法がちょっと違うのみです。

  • JavaScript
const countries = ['Japan', 'China', 'Korea', 'United States', 'Brazil'];
countries.length; // 5(長さを返す)
countries[0]; // Japan
countries.push('Tai'); // 追加
const countries2 = ['Itally', 'France'];
const countries3 = [...countries, ...countries2]; // 展開する(この例では展開して結合)
  • Python
countries = ['Japan', 'China', 'Korea', 'United States', 'Brazil']
print(len(countries))  # 5(長さを返す)
print(countries[0])  # Japan
countries.append('Tai')  # 追加

# ['Japan', 'China', 'Korea', 'United States', 'Brazil', 'Tai']
print(countries)

countries2 = ['Itally', 'France']
countries3 = [*countries, *countries2]  # 展開する(この例では展開して結合)

# ['Japan', 'China', 'Korea', 'United States', 'Brazil', 'Tai', 'Itally', 'France']
print(countries3)

個人的にPythonで便利だなと思ったのはこれです。

  • Python
num_list = [1, 2, 3, 4, 5, 6]
print(num_list[0:2])  # [1, 2](0番目から2番目まで)
print(num_list[3:])  # [4, 5, 6](3番目から最後まで)
print(num_list[3:-1])  # [4, 5](3番目から2つ前まで)

また、PythonにはTupleという型もあります。
ただ、これは固定長で順序や値の変更ができません。

  • Python
thistuple = ("apple", "banana", "cherry")
print(thistuple) # ('apple', 'banana', 'cherry')

オブジェクト(Pythonでは辞書型)

名称は違いますが大体同じです。

  • JavaScript
# `name`でも大丈夫です
const person = {
  name: 'Miki',
  age: 24
}
console.log(person.name) # Miki
console.log(person['age']) # 24(こちらでも)
  • Python
person = {
  'name': 'Miki',
  'age': 24
}
print(person['age']) # 24

Pythonは未定義かどうかチェックする便利なメソッドがあります。

  • Python
person.get('gender', 'undefined') # Rerutn undefined

Null型(PythonではNone)

JavaScriptでのnullはPythonではNoneに該当します。JavaScriptにはundefinedがありますが、Pythonにはありません。
なおいずれもFalsyです。

  • JavaScript
let x;
console.log(x); // これはundefined
console.log(!!x); // False
x = null;
console.log(x); // null
console.log(!!x); // False
  • Python
x = None
print(x); # None
print(not not x)  # False

オペレータ

論理演算子

PythonはSQLとかで使われるような表記です。

JavaScript Python
かつ and &&
または or ||
否定 not !

算術演算子

JavaScript Python
超過 > >
未満 < <
以上 >= >=
以下 <= <=
等しい == ==
厳密に等しい(※1) === なし
等しくない != !=

※1:厳密なイコールについて
JavaScriptやってる人ならおなじみだと思いますが一応

  • JavaScript
'1' == 1 // TRUE(型変換をしてくれる)
'1' === 1 // FALSE
1 === 1 // TRUE

なお、Pythonは==で型変換まではしてくれません。

  • Python
'1' == 1 # False

繰り返し処理

さして違いはありません。

  • JavaScript
// Array型のイテレーション
const students = ['Lee', 'Toni', 'Marie', 'Jesse', 'Anwar']
for (const student of students) {
  console.log(student); // Lee, Toni, Marie...
}
// Object型のイテレーション
dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
for (const key in dict){ 
    console.log(key); // color、fruit...
}
  • Python
# Array型のイテレーション
students = ['Lee', 'Toni', 'Marie', 'Jesse', 'Anwar']
for student in students:
    print(student); # Lee, Toni, Marie...

# Distionary型のイテレーション
dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
for key in dict:
    print(key) # color、fruit...

関数

これも表記が違うだけでほぼ似たような感じです。

  • JavaScript
function add(a, b) {
  const result = a + b;
  return result;
}

// アロー関数
const arrowAdd = (a, b) => a + b;
// 無名関数を使ってみる
const students = ['Lee', 'Toni', 'Marie', 'Jesse', 'Anwar'];
students.map(s => s.toUpperCase()); // [LEE, TONI, MARIE...]
  • Python
def add(a, b):
    result = a + b
    return result
 
# labmdaキーワードで表す
lambda_add_function = lambda a,b : a + b
# 無名関数を使ってみる
students = ['Lee', 'Toni', 'Marie', 'Jesse', 'Anwar']
list( map(lambda s: s.upper(), students) ) # [LEE, TONI, MARIE...]

// Pythonの高階関数はなんか不思議な感じがする、、、

クラス・インスタンス関連

  • JavaScript
class Person {
    // staticフィールド
    static defaultAge = 0;

    // privateメソッド
    #age;

    // コンストラクタ
    constructor(name, age) {
        this.name = name;
        this.#age = age || this.defaultAge;
    }
    // staticメソッド
    static sayHello = () => console.log("Hello!");

    // privateメソッド
    #getAge = () => this.#age;
    // publicメソッド
    sayAge = () => console.log(`I'm ${this.#getAge()} years old.`);
}

class Developer extends Person {
    constructor(name, age, yearsOfExperience) {
        super(name, age);
        this.yearsOfExperience = yearsOfExperience;
    }
}

// static(インスタンスがなくても実行できる)メソッドとフィールド
console.log(Person.defaultAge); // 0
Person.sayHello(); //Hello!

const p1 = new Person("Lee", 21);
const p2 = new Person("Baby");
console.log(p1); // Person { sayAge: [Function: sayAge], name: 'Lee' }
console.log(p2); // Person { sayAge: [Function: sayAge], name: 'Baby' }

// privateメソッドはアクセスできない
// console.log(p1.#age); // SyntaxError: Private field '#age' must be declared in an enclosing class
// console.log(p1.#getAge()); // SyntaxError: Private field '#getAge' must be declared in an enclosing class

// publicは使える
p1.sayAge(); // I'm 21 years old.

// Personを継承したクラス
const p3 = new Developer("Miki", 28, 6);
console.log(p3); // Developer { sayAge: [Function: sayAge], name: 'Miki', yearsOfExperience: 6 }
p3.sayAge(); // I'm 28 years old.
  • Python

class Person:
    # staticフィールド
    defaultAge = 0

    # コンストラクタ
    def __init__(self, name, age=defaultAge):
        self.name = name
        self.__age = age

    # staticメソッド
    @staticmethod
    def sayHello():
        print("Hello!")

    # privateメソッド
    def __getAge(self):
        return self.__age

    # publicメソッド
    def sayAge(self):
        print("I'm %s years old." % (self.__getAge()))

    # printで表示できるように
    def __repr__(self):
        return "<Person name:%s>" % (self.name)


class Developer(Person):
    def __init__(self, name, age, years_of_experience):
        super().__init__(name, age)
        self.years_of_experience = years_of_experience

    # printで表示できるように
    def __repr__(self):
        return "<Developer name:%s years_of_experience:%s >" % (self.name, self.years_of_experience)


# static(インスタンスがなくても実行できる)メソッドとフィールド
print(Person.defaultAge)  # 0
Person.sayHello()  # Hello!

p1 = Person("Lee", 21)
p2 = Person("Baby")
print(p1)  # <Person name:Lee>
print(p2)  # <Person name:Baby>

# privateメソッドはアクセスできない
# print(p1.__age)
# print(p1.__getAge())

# publicは使える
p1.sayAge()  # I'm 21 years old.

# Personを継承したクラス
p3 = Developer("Miki", 28, 6)
print(p3)  # <Developer name:Miki years_of_experience:6 >
p3.sayAge()  # I'm 28 years old.

モジュールのimport

JavaScriptのように、moduleをexportする必要はありません。

JavaScriptはとりあえずrequireで比較例を記載しておきます。

  • JavaScript

testModule.js

const str = 'test module is called';
function say() {
    console.log(str);
}
exports.say = say;

index.js

const testModule = require("./testModule");
testModule.say();
  • Python

testModule.js

const testModule = require("./testModule");
testModule.say();

testModule.js

const testModule = require("./testModule");
testModule.say();

さいごに

どなたかのお役に立てれば幸いです!
ここまで読んでくれてありがとうございます。

Discussion