2009年11月3日火曜日

URLエンコード

PythonでURLエンコードを行うにはurllibライブラリのquote_plus関数を使用します。

例)Python

import urllib

urlenc_param = urllib.quote_plus(param.encode('utf8'))


例)Java
※メソッド宣言は省略しています。

import java.net.URLEncoder;

String urlenc_param = URLEncoder.encode(param, "UTF-8");

2009年10月19日月曜日

StringBufferにはjoin()を代用する

文字列の連結を行うにはバッファリングを行った方が効率的です。JavaではStringBufferを用いますが、Pythonでははjoin()関数を利用します。

例)Python

buffer = []

for i in range(100):
buffer.append(str(i))

print ''.join(buffer)

例)Java

StringBuffer buffer = new StringBuffer(100);

for(int i = 0; i < 100; i++) {
buffer.append(String.valurof(i));
}

System.out.println(buffer.toString());

2009年10月9日金曜日

辞書にはKeyの存在を問合せる必要あり

Pythonの辞書(JavaではMap)から値を取り出す際に存在しないキーを指定するとエラーになってしまいます。
そのため取得を行う前にhas_key()を用いてキーの存在を問合せる必要があります。

例)Python

value = None

if map.has_key("hoge"):
value = map["hoge"]

例)Java
JavaのMapインターフェースではKeyが存在しない場合はnullを返すことが定義されています。

String value = (String)map.get("hoge");

2009年10月5日月曜日

インクリメント for ループ

インクリメントのforループです。

例)Python

"range(100)"は「100個の配列を生成する」という関数で、"0"から始まり"99"までとなります。

for i in range(100): # 変数iを0から99までインクリメントして繰り返す。
print i
例)Java

for (int i = 0; 100 > i; i++) {
System.out.pritln(i);
}

2009年10月1日木曜日

システム日付の取得

Pythonでのシステム日付の取得はdateオブジェクトを用います。

例)Python

from datetime import date

date.today().year
date.today().month
date.today().day

date.isoformat(date.today())
出力)

> 2009
> 10
> 1
> '2009-10-01'

例)Java

System.out.println(Calendar.getInstance().get(Calendar.YEAR));
System.out.println(Calendar.getInstance().get(Calendar.MONTH));
System.out.println(Calendar.getInstance().get(Calendar.DAY_OF_MONTH));

SimpleDateFormat sdf = new SimpleDateFormat("yyyy'-'MM'-'dd");
System.out.println(sdf.format(Calendar.getInstance().getTime()));

2009年9月21日月曜日

super

Pythonにおいて継承した親クラスを明示する方法はJavaと同様、キーワード"super"を使用します。
例)Python

class Employee(Person):
def __init__(self):
super.__init__(self) # 親クラスの初期化メソッドを呼び出し。
例)Java

public class Employee extends Person {

public Employee() {
super(); // 親クラスのコンストラクタ呼び出し。
}
}

2009年9月15日火曜日

クラスの継承

PythonではJavaではできない多重継承が可能です。

例)Python

# 単継承
class SingleExtendsClass(Base1):
<文-1>
.
.
.
<文-N>

# 多重継承
class MultiExtendsClass(Base1, Base2, Base3):
<文-1>
.
.
.
<文-N>
例)Java

/**
* 単継承しかできない。
*/
public class SingleExtendsClass extends Base1 {
<文-1>
.
.
.
<文-N>
}

2009年9月8日火曜日

インスタンスの生成

Pythonではインスタンス生成の際にJavaでいうnewキーワードは不要です。

例)Python

class Employee:
pass

john = Employee()
例)Java

public class Employee() {
private pass;
}

john = new Employee();

2009年8月22日土曜日

文字列のフォーマット(数字編)

Phthonにおける文字列のフォーマットはJavaのMessageFormatと比べるとだいぶ様子が異なります。

例)Python
  • フォーマットを文字列で定義します。
  • %に続けてフォーマットコードを記述すると、そこに文字列がバインドされます。たとえば"%s"(文字列)、"%d"(10進数整数)など。一覧はコチラをご覧ください。
  • 数字の精度を指定する場合は"%[符号][ゼロ埋めするか][整数桁数].[浮動小数桁数]f"と定義します。
  • バインドする値は"%"で区切って指定します。

FORM = "%02.3f" # 符号なし、ゼロ埋めあり、整数2桁、小数3桁
x = float(1)
y = float(3)

print FORM % (x / y) # 値のバインド
出力)
> 00.333
例)Java
型が厳密な故にMessageFormat#format()メソッドの引数をObject型にしなければならないのが煩わしいですね。

final MessageFormat FORM = new MessageFormat("{0, number, ##.##}");
float x = (float)1;
float y = (float)3;
Object[] args = {new Float(x / y)};
System.out.println(FORM.format(args));

2009年8月13日木曜日

日本語のリテラル定義

Pythonインタプリタの内部コードはJava同様ユニコードです。ですが、日本語をリテラルとして定義する場合、Javaでは他のASCII文字列との区別を意識しませんがPythonにおいてはユニコードで扱うことを明示する必要があります。

例)Python


name = u"山田太郎"


例)Java


String name = "山田太郎";

2009年8月12日水曜日

ソースファイルの文字コード

Pythonをスクリプトファイルとして実行する場合は当然ソースファイルを用意します。Pythonはスクリプト言語ですのでJavaのようにコンパイルという作業はありません。そのためスクリプトファイルの先頭でソースファイルの文字コードを指定することにより、インタプリタへ通知します。

例)Python
1行目が文字コード宣言になります。

# -*- coding: utf-8 -*-
'''
Created on 2009/05/19

@author: hogehoge
'''
from google.appengine.ext import db
from datetime import date

例)Java
Javaのの場合はコンパイル時に"-encoding"オプションを指定することによりソースファイルの文字コードを指定し、ハードコーディングされたマルチバイト文字の文字化けを回避できます。

> javac -encoding utf-8 hogehoge.java

2009年8月3日月曜日

importとモジュールと関数と

Pythonにおけるimportを理解するためには、まずJavaとは異なる下記を理解する必要があります。
  • モジュール・・・クラスや関数が定義されているファイルのこと。

  • 関数、クラス・・・モジュール内に定義されている関数、クラス。

  • パッケージ・・・モジュール(≒ファイル)が配置されているディレクトリパス。

キーワードimportは単体で指定する場合と、キーワードfromとペアで指定する場合により指定するものが変わります。
単体で指定する場合は「モジュール」を指定し、fromとペアの場合は「関数」または「クラス」を指定します。

例)Python

import re # モジュールをインポート
from datetime import date # datetimeモジュールからdateクラスをインポート
from calendar import * # Java同様ワイルドカードも使える
from math import sin, cos, tan # 複数関数を指定

print re.split('\W+', 'Words, words, words.')
print date.today()
print firstweek() # calendarモジュールの関数

例)Java

import java.util.regex.*;
import java.util.Date;
import java.util.Calendar;

モジュールという仕組みがあるので、importしかないJavaに比べるとちょっとややこしいですが、慣れればね。

2009年7月27日月曜日

Mapは辞書オブジェクト

JavaのHashMapクラスにあたるものはPythonでは辞書オブジェクトといいます。
Map同様、キーと値のペアを定義できます。

例)Python

colors = {"red":"#FF0000", "green":"#F00FF00", "blue":"#0000FF"}

print colors["red"] # keyを指定して値を取得
print colors.keys() # キー一覧を取得

例)Java

HashMap colors = new HashMap();
colors.put("red", "#FF0000");
colors.put("green", "#00FF00");
colors.put("blue", "#0000FF");

System.out.println(colors.get("red"));
System.out.println(colors.keys());

2009年7月22日水曜日

配列サイズの取得は len()

Pythonでは配列のサイズ取得に組み込み関数のlen()を使用します。

例)Python

numbers = [1, 2, 3, 4, 5]
print len(numbers)

例)Java

int[] numbers = {1, 2, 3, 4, 5};
System.out.println(numbers.length)

2009年7月18日土曜日

メソッドではなく関数

Javaではメソッドは必ずクラスに定義されている必要がありますが、Pythonはスクリプト言語であり、クラス定義は必須ではありません。
クラスに属さないメソッドにあたる処理単位を「関数」と呼び、関数はモジュールに属します。
モジュールについては別途記事にするつもりですが、簡単に言うと関数群が定義されたファイルのことです。
なお、関数の書式はメソッドとほぼ同じですが、クラスに属さないのでインデントがトップになり、メソッドの場合に第1引数に指定した自分自身のインスタンスを表す"self"が不要となります。

例)Python

def hello():
print "hello!"

hello()
上記をファイル名"hello.py"として保存し実行すると、4行目が実行されます。

> python hello.py
hello!

2009年7月13日月曜日

for文

PythonではJavaの拡張for文と同じような記述になります。とてもシンプルです。

例)Python

numbers = [10, 20, 30]

for num in numbers:
print num

例)Java
フツーのfor文

int[] numbers = {10, 20, 30};

for(int i = 0; numbers.length > i; i++) {
System.out.println(numbers[i]);
}
拡張for文

int[] numbers = {10, 20, 30};

for(int num : numbers) {
System.out.println(num);
}

2009年7月12日日曜日

if文

if文はJavaにおける「else if」に対して「elif」と記述します。また論理演算子が異なりJavaの"&&"には"and"、"||"には"or"が対応します。詳しくは論理演算子の投稿でまとめます。

例)Python

if 28 <= age and age <= 33:
print "around 30!"
elif 38 <= age and age <= 43:
print "around 40!"

例)Java

if(28 <= age && age <= 33) {
Sysem.out.println("around 30!");
}
else if(38 <= age && age <= 43) {
System.out.println("around 40!");
}

2009年7月9日木曜日

nullではなくNone

Pythonでは値が存在しないことを示すキーワードは"None"です。大文字小文字を区別します。これはJavaでいう"null"にあたります。
Pythonでは変数の型を意識しませんので、オブジェクトでも数字でも変数ならNoneを代入できます。

例)Python

person = None
person = 100
person = Person()

例)Java

Person person = null;
person = new Person();
person = 100; // <- 当然コンパイルエラー

2009年7月5日日曜日

メソッドの定義

Pythonのインスタンスメソッドの扱いはJavaと非常に似ていますが、宣言方法や作法がいくつか異なります。

例)Python
  • 宣言は"def"で行います。
  • メソッド名は全て小文字で記述し、単語の区切りにアンダースコアを使用するのが一般的なようです。
  • 戻り値の定義は必要ありません。
  • 第1引数は自分自身のインスタンスを示す"self"となります。

class Person:

__name = None

def get_name(self):
return self.__name

例)Java

public class Person {

private String name = null;

public String getName {
return this.name;
}
}

Javaと比較すると変数の宣言同様、戻り値の型定義をしないことに非常に違和感がありますね。この辺りがユルイというか、Javaの方が厳格だと言われる所以でしょう。

2009年7月2日木曜日

コメント

コメントの記述方法です。

例)Python
Pythonではブロックコメントの記述方法がありませんが、3重クォーテーションによる改行を含んだ文字列定義で代用をするのが一般的なようです。

# 1行コメント
str = "hogehoge" # これも1行コメント

'''
# ブロックコメントに代用
x = 1
y = 2
print x + y
'''

例)Java

// 1行コメント
String str = "hogehoge"; // これも1行コメント

/*
// ブロックコメント
int x = 1;
int y = 2;
System.out.println(x + y);
*/

2009年7月1日水曜日

コンストラクタは"__init__()"

Pythonにおいてもインスタンスの初期化を行う場合にJavaのコンストラクタにあたる"__init__()"メソッドがあります。

例)Python
第1引数の"self"はJavaでいうthisと同様の意味合いで、自分自身のインスタンスを示します。__init__()に限らずインスタンスメソッドにおいても第1引数はかならずこのselfになるので、イヤというほどお目にかかることになります。

class Person:
__name = None
__age = None

def __init__(self, name, age):
self.__name = name
self.__age = age

例)Java

public class Person {
private String name = null;
private short age = -1;

public Person(String name, short age) {
this.name = name;
this.age = age;
}
}

2009年6月30日火曜日

クラス定義

PythonにおいてもJava同様クラスを定義することが可能です。

例)Python
  • アクセス修飾子はありません。
  • Pythonでは "{", "}" は使用しませんので、クラス宣言の末尾は ":" となります。
  • クラス名の先頭文字はJava同様大文字ではじめるのが一般的なようです。
  • 属性をカプセル化する場合は属性名の先頭に "__"(アンダースコア2つ)を付与します。
class Person:
__name = None
__age = None

例)Java

public class Person {
private String name = null;
private short age = -1;
}

これだけを見てもPythonはコードが少なくシンプルですね。単純にコーディング量が少なくなります。もちろんJavaの方が制御が厳密で堅牢ではありますが。適材適所が大切ですね。

2009年6月29日月曜日

完全なカプセル化は行えない

Javaでインスタンス変数を隠蔽してカプセル化を行う場合は変数にprivate修飾子を指定します。
Pythonにおいては変数名の先頭に"__"とアンダーバーを2つ付けることで同様の意味を持たせることが可能です。

例)Python
下記classの変数"__name"にはアクセスできない。

class Person:
__name = "hoge"

p = Person()
print p.__name # <- AttributeError: Person instance has no attribute '__name'

実はこれ、内部的には変数が別名に置き換わって定義され、その別名を指定すると直接アクセスすることが可能なようです。
擬似的にprivateを実現させているものですが、実用上は問題ありませんね。

2009年6月28日日曜日

Pythonの変数には型がない

Pythonの変数には型がありません。Javaは厳格に型定義を行いますので、これがJavaとは大きく異なる要素の1つです。私はEclipseを利用しているので、Javaの場合は実装中に警告をしてくれますが、Pythonでは実行させるまで間違いに気づけません。正直私はまだ馴染めていません。

例)Python
こんな風に数字でも文字列でも配列でも何でも代入できてしまいます。

hoge = -99
hoge = "abc"
hoge = [1, 2, 3]

このため、長いロジック内部などにおいて新たな変数を定義したつもりでいても、すでに定義済みの変数名と重複させてしまうと代入として処理されてしまいバグの原因になってしまうので注意が必要です。