※注意 気づいたものを順次追記する
java屋さんがpythonを使いだして、違いにびっくりしたものを列挙する。
またその対処方法を残す。
switch文
pythonにはswitchにあたる構文がない。
switchがなければifでやればいいじゃないという発想らしい。
もしくは辞書を使った方法もある。
Python に switch や case 文がないのはなぜですか?(公式サイト)
def function_1():
print('function_1!')
def function_2():
print('function_2!')
functions = {'a': function_1, 'b': function_2}
func = functions['b']
func()
↓実行結果↓
function_1!
定数
pythonには厳密な定数はなく、
全部大文字に命名することで運用的に定数のように扱う。
単なる変数なので当然その気になれば変更できる。
インターフェイス
pythonにはインターフェイスが存在しない。
ABC(Abstract Base Classes)という抽象クラスの概念はあるので特に困らないかな。
全部抽象メソッドにすればいいだけ。
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
class Cow(Animal):
def sound(self):
print("moo")
class Penguin(Animal):
pass # 抽象メソッドを実装していない
if __name__ == "__main__":
hanako = Cow()
hanako.sound()
taro = Penguin() # 抽象メソッドを実装していないのでインスタンス化時にエラーになる
moo
Traceback (most recent call last):
File "abctest.py", line 19, in <module>
taro = Penguin()
TypeError: Can't instantiate abstract class Penguin with abstract methods sound
オーバーロード
pythonにはオーバーロードという概念がない。
オーバーロードのようなことをするには引数のデフォルト設定や可変長引数を使う。
オーバーロードしようとするとエラーになる例
class Farm:
def add(self, animal):
print(animal)
def add(self, animal1, animal2):
print(animal1)
print(animal2)
if __name__ == "__main__":
farm = Farm()
farm.add('Dog')
farm.add('Jersey','Holstein')
↓実行結果↓
Traceback (most recent call last):
File "farmtest.py", line 13, in <module>
farm.add()
TypeError: add() missing 2 required positional arguments: 'animal1' and 'animal2'
これはOK
class Farm:
def add(self, animal='Chicken'):
print(animal)
if __name__ == "__main__":
farm = Farm()
farm.add()
farm.add('Dog')
↓実行結果↓
Chicken
Dog
class Farm:
def add(self, *args):
if len(args) == 0:
print('blank')
for i in args:
print(i)
if __name__ == "__main__":
farm = Farm()
farm.add()
farm.add('Dog')
farm.add('Jersey','Holstein')
↓実行結果↓
blank
Dog
Jersey
Holstein
ApplicationContext
JavaのServletやspringframeworkでSessionスコープより広範囲のApplicationContextに該当するものはdjangoにはない。
djangoを使っているから?
ラベル付きbreak
javaで2重ループから一気に抜け出すようなときに使うラベル付きbreakはpythonにない。
javaでもあまり使わないから、まいいか。
ローカル変数の有効範囲(スコープ)
pythonは関数内有効。
javaはブロック内有効。
これは、、java屋さんからすると扱いづらい・・・。
フィールド定義位置
javaのインスタンス変数のような書き方をするとpythonではクラス変数の意味になってしまうので注意!
最初うっかり書き間違えたら動きが想定外になってびっくりした。
class Cow:
type = 'Holstein' # クラス変数
def __init__(self, name): # コンストラクタ
self.name = name # インスタンス変数
def walk(self):
print(self.name + 'が歩く')
hanako = Cow('はなこ')
hanako.walk()
↓実行結果↓
はなこが歩く
class Cow {
private static String type = "Holstein" // クラス変数
private String name; // インスタンス変数
public Cow(String name) { // コンストラクタ
this.name = name;
}
public void walk() {
System.out.println(this.name + "が歩く");
}
}
class Main {
public static void main(String[] args) {
Cow hanako = new Cow("はなこ");
hanako.walk();
}
}
↓実行結果↓
はなこが歩く