Oct 9, 2012

Làm quen với Jython (Phần 5 - Kiểu dữ liệu)

Định danh và kiểu dữ liệu trong Jython

Định danh (identifier) trong Jython được quy định tương tự như Java, đó là tập các từ khóa có sẵn và quy tắc đặt tên cho biến, phương thức, ... Danh sách các từ khóa có sẵn xin xem thêm tại: http://www.jython.org/jythonbook/en/1.0/LangSyntax.html#identifiers-and-declaring-variables

Các đối tượng dữ liệu (data object) trong Jython
     Các đối tượng dữ liệu trong Jython được xây dựng dựa trên các đặc tả của Python. Các kiểu được đặt tên như integer, long, float, complex, string, tuple, list, dictionary. Jython không có kiểu dữ liệu nếu hiểu theo cách như các ngôn ngữ khác, bởi ở Jython chúng chỉ là các đặc tả dữ liệu (data descriptor) chứ không phải là một class hay instance nào cụ thể. Các dữ liệu được biểu diễn bởi các Java class nằm trong package org.python.core, do đó Jython không có kiểu dữ liệu nguyên thủy.
     Tên các Java class biểu diễn các kiểu của Python được đặt tiếp đầu ngữ là "Py", ví dụ PyInteger, PyComplex, PyTuple, ... Các class dùng cho dữ liệu có tính động, và được quyết định lúc thực thi.



Kiểu dữ liệu số (Numeric)
     Các class có vai trò biểu diễn các đối tượng numeric của Jython gồm có PyInteger, PyLong, PyFloat và PyComplex. Các biến kiểu numeric thu được từ việc gán một giá trị numeric phù hợp, và nếu như ta gán một biến cho một số dạng complex thì số đó sẽ được biểu diễn bởi class PyComplex.

- PyInteger: ứng với kiểu int trong Java, biểu diễn được 4 bytes
- PyLong: ứng với kiểu long trong Java, số được biểu diễn kèm kí tự l hoặc L ở cuối để chỉ định là long
- PyFloat: kiểu dấu chấm động, ứng với kiểu double trong Java, biểu diễn với 8 byte dữ liệu
- PyComplex: Một số phức tạp được biểu diễn bởi hai số chấm động. Trong đó, số đầu tiên biểu diễn phần thực và số thứ hai biểu diễn phần ảo.

Kiểu chuỗi (sequence)
     Các dữ liệu kiểu chuỗi trong Jython được biểu diễn bởi các class PyString, PyTuple, PyList. Trong đó, PyString chỉ chứa các dữ liệu xâu ký tự, còn PyTuple và PyList có thể chứa các phần tử kiểu dữ liệu bất kỳ.
Đặc trưng của kiểu chuỗi so với kiểu số đó là kiểu chuỗi có mô tả độ dài.
     Các kiểu dữ liệu chuỗi có khác nhau chút ít về cách khởi tạo nhưng cùng chung cách truy cập các phần tử đó là dùng cặp ngoặc vuông [] để chỉ định index của phần tử đó. Ví dụ:

>>>#khoi tao
>>>S = "abc"            # This is a string 
>>>T = ("a", "b", "c")  # This is a tuple 
>>>L = ["a", "b", "c"]  # This is a list 
>>>#Truy cap
>>>S[1] 
'b' 
>>>T[1] 
'b' 
>>>L[1] 
'b'


    Chỉ số của phần tử trong sequence được tính từ 0 trở đi, từ trái sang phải. Chỉ số này có thể âm, khi đó nó sẽ biểu diễn vị trí tính từ phải sang, khi đó kí tự cuối cùng sẽ có chỉ số là -1. Ví dụ:
>>> string="abc123"
>>> string[-1]
'3'
>>> string[0]
'a'
>>> string[-2]
'2'
>>> 


Việc lấy một chuỗi con (sequence's slice)
     Việc cắt một chuỗi con sẽ được thực hiện bằng cách chỉ định điểm mốc hai đầu chuỗi con cần lấy. Hai chỉ sổ này được phân tách nhau bởi dấu hai chấm. Trong đó, chuỗi được lấy sẽ gồm phần tử có index thứ nhất cho đến phần tử đứng trước vị trí index thứ hai, tức là không bao gồm phần tử index thứ hai.
    Ví dụ:

>>>S = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>>S[3:6] # slice from 3 up to, but not including 6 
[4, 5, 6]

    Một chuỗi con dạng S[index1:] sẽ lấy chuỗi tính từ index1 đến kết thúc. Còn một chuỗi con dạng S[4:-2] sẽ lấy từ vị trí thứ 4 đến trước vị trí thứ 2 từ phải sang.

    Jython cũng hỗ trợ sử dụng ba chỉ số để lấy chuỗi con trong một khoảng chỉ định nhưng "nhảy cóc" một số bước chứ không lấy liên tục. Ví dụ một chuỗi con xác định bởi S[2:8:3] sẽ xác định một chuỗi con tính từ vị trí thứ 2 tới trước vị trí thứ 8, trong đó mỗi bước nhảy để lấy phần tử tiếp theo là 3. Cụ thể:

>>> S = 'zahbexlwlvo2 fwzo4rslmd' 
>>> S[2::2] # this slices from index 2 to the endpoint, steping by 2 
'hello world' 
>>> 
>>> L = [1,2,3,4,5,6,7,8,9] 
>>> L[-1:3:-1] # last index to third index, indexes step by -1 
[9, 8, 7, 6, 5]

    Với các kiểu chuỗi mà không thay đổi được ví dụ như PyString hay PyTuple ta có thể truy cập tới các phần tử, nhưng không thể thay đổi giá trị của chúng được.

Kiểu dữ liệu PyString
     Java class này thừa kế các thuộc tính của Java string theo cách chúng được tạo thành từ các ký tự 2 byte dựa theo chuẩn Unicode 2.0, khác với Pyt thon dựa trên 8bit và 16bit theo chuẩn Unicode 3.0.
     Một đối tượng string được tạo thành từ việc gán một string cho một biến. Để biểu diễn một string, có thể dùng cặp nháy đơn, nháy đôi (' hay ") hoặc cặp ba nháy (''' hay """). Các dấu nháy loại này có thể xuất hiện bên trong cặp dấu nháy của loại kia một cách hợp lệ. Cách nhúng dấu nháy vào trong một string để hiển thị nó là hợp lệ, nhưng chỉ với phép ghép giữa các string thuần túy (literal string tức là các string không thay đổi được), chứ không thể đem ghép với các số hay các biến mang giá trị.

Kiểu PyTuple
     Class PyTuple là một dạng chuỗi không sửa đổi được, có thể chứa các tham chiếu tới bất kỳ kiểu dữ liệu nào. Mặc dù nó là immutable nhưng có thể chứa các dữ liệu mutable, điều này có được là bởi vì bản thân nó không chứa dữ liệu thành viên mà chỉ chứa các tham chiếu tới chúng.
     Để biểu diễn một tuple có thể dùng nhiều cách như bao trong cặp () và mỗi thành phần tách nhau bởi dấu phảy; không dùng cặp ngoặc () mỗi phần tử tách nhau bởi dấu phảy; hoặc chỉ cặp ngoặc () cho tuple trống.
     Ví dụ:

>>>t = (1,2,3) 
>>>type(t) 
<jclass org.python.core.PyTuple at 6879429> 
>>>t = 1,2,3 
>>>type(t) 
<jclass org.python.core.PyTuple at 6879429> 
>>> type((1,2,3)) 
<jclass org.python.core.PyTuple at 6879329> 
>>>myTuple = (1, "string", 11.5)  # tuples can contain any object type


     Việc khai báo và khởi tạo một tuple đơn phần tử cũng đòi hỏi phải có thêm một dấu phảy sau phần tử đó:
>>> t1 = ("element one",) 
>>> t2 = "element one", 
>>> type(t1) 
<jclass org.python.core.PyTuple at 4229391> 
>>> type(t2) 
<jclass org.python.core.PyTuple at 4229391> 
>>> print t1 
('element one',) 
>>> print t2 
('element one',)

Kiểu PyList
     PyList tương đồng với PyTuple, có điều PyList là mutable, tức có thể sửa đổi trực tiếp giá trị các thành phần trong PyList. Các phần tử trong PyList được bao bởi cặp ngoặc vuông, giống như mảng trong Java.

Kiểu bảng băm, từ điển
     Trong Jython có hai kiểu bảng băm, ánh xạ, hay còn gọi là từ điển. Việc ánh xạ xem như là phép ánh xạ từ một key dạng immutable tới một value. Khác biệt giữa hai kiểu ánh xạ đó là kiểu dữ liệu mà key sử dụng.
   Xét kiểu thứ nhất: PyDictionary
     Kiểu từ điển này tổ hợp từ các cặp key:value được bao bởi cặp {}. Các key có thể có thuộc nhiều kiểu khác nhau, nhưng phải là immutable. Một kiểu mutable không thể được dùng làm key của PyDictionary, ví dụ:

>>> list=[1,2,3,4] # this is a mutable sequence / list
>>> D = {list:"my key is a list"}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> 

     Một lưu ý quan trọng nữa về key đó là các giá trị số được sử dụng làm key sẽ được hash theo cách mà giá trị của chúng được so sánh. Giá trị PyInteger 1 là một object khác so với PyFloat 1.0, nhưng chúng được so sánh bằng nhau và do đó nảy sinh chuyện có hai key trong một từ điển.

   Kiểu từ điển thứ hai PyStringMap
     Với kiểu từ điển này, chỉ có các xâu ký tự (string) được sử dụng làm key. Khác biệt so với PyDictionary vì PyDictionary nhận bất cứ kiểu immutable nào. Loại object này không đơn giản chỉ là sinh ra từ các nhà phát triển Jython, mà nó vốn được trả về mởi một số hàm có sẵn. Nó sinh ra vì một số lý do hiệu năng.
PyStringMap hầu hết được sử dụng cho các namespace do chúng sử dụng key là các string.

Kiểu PyNone
     None là một trạng thái đặc biệt của giá trị, None cũng tương đương như null trong Java. PyNone là class biểu diễn giá trị None.

No comments:

Post a Comment