Python có đáng sợ thế không?

Ngày nay, hẳn các bạn đã nghe nhiều đến Python, một thứ ngôn ngữ lập trình có cú pháp cực kì đáng sợ, khó đọc, khó nhớ, chả ai thèm dùng. Có một thực tế là hiện nay, các chương trình đào tạo CNTT của các trường ĐH trên thế giới đều bắt đầu chuyển sang sử dụng Python làm ngôn ngữ lập trình căn bản cho sinh viên. Tại sao vậy? Chả biết, mình viết bài này không phải để trả lời mấy câu hỏi này…

Chắc các bạn cũng từng không dưới một lần bắt gặp một đoạn code Python ở đâu đó trên mạng, len lén nhìn vào nó phát rồi scroll đi không thèm đọc, chỉ vì cái định kiến chả biết từ đâu ra răng nó xấu quá, cú pháp gì mà thò tới thụt lui, ko có đóng mở gì,… blah blah blah…

Quay trở lại câu hỏi tại sao, giờ mình hỏi ngược lại, tại sao bạn lại sợ nó đến vậy? Có phải vì bạn đã quen với cấu trúc có mở có đóng như PHP, C++, C#, Java hay thậm chí là… Pascal rồi, nên nhìn vào code Python bạn chỉ thấy một đống bùi nhùi không? :D

Nếu đúng là như vậy, có lẽ bài viết này sẽ phần nào giúp bạn có thêm can đảm dẹp bỏ cái định kiến vô lý kia và dấn thân vào tìm hiểu thứ ngôn ngữ lợi hại này một cách dễ dàng hơn.

Học là phải đi đôi với hành, mình nghĩ các bạn nên chuẩn bị sẵn một trình soạn thảo và một bộ Python cài sẵn trong máy để vừa đọc vừa gõ gõ theo một vài ví dụ, như vậy hiệu quả hơn.

Cài đặt

Đối với các bạn xài Windows, có thể tải Python về tại đây. Các bước cài đặt khá là đơn giản nên mình cũng không cần ghi ra đây.

Đối với các bạn dùng hệ điều hành Linux hoặc Mac OS thì khoẻ re vì đã có sẵn Python kèm theo hệ điều hành rồi.

Về editor thì các bạn có thể dùng bất kì editor nào tuỳ thích, Notepad cũng được, Notepad++, EditPlus gì cũng được tuốt. Mình khuyến khích dùng Sublime Text, đây là một editor khá là đa năng, có tích hợp sẵn chức năng build và chạy code Python (và nhiều ngôn ngữ khác).

 Dạo đầu, Hello World!

Giống như bất cứ bài học lập trình khác, đây là một chương trình Hello World viết bằng Python.

1
print('Hello World!')

Bạn có thể gõ nó vào editor rồi lưu với tên gì đó, hello.py chẳng hạn.

Để chạy chương trình Python đầu tiên của chúng ta, hãy mở Terminal (hoặc Command Line nếu bạn xài Windows) và gõ:

python hello.py

Bạn sẽ thấy dòng chữ Hello World! hiện ra trên màn hình.

Vậy, qua cái ví dụ cơ bản (có bạn sẽ nói nó tào lao, cũng không hẳn là sai :D) này, chúng ta học được cái gì?

  1. Python không dùng dấu chấm phẩy ở cuối mỗi dòng lệnh
  2. Một chương trình Python luôn được chạy bằng câu lệnh “python <tên file>.py”

 Cú pháp của Python

Qua ví dụ trên, chúng ta đã thấy được một điểm khác biệt của Python so với các ngôn ngữ lập trình C-like (anh em họ hàng với C: C++, C#, Java, PHP…) mà chúng ta thường dùng, đó là không cần dùng dấu chấm phẩy ở cuối mỗi dòng lệnh.

Ngoài ra,  còn có 2 yếu tố nữa mà các bạn cần phải biết khi sử dụng Python, đó là dấu hai chấm  :  và thụt đầu dòng.

Tương tự như cặp dấu ngoặc nhọn  { }  trong các ngôn ngữ C-like, một khối lệnh của Python sẽ được bắt đầu bằng một dấu 2 chấm, và một dấu thụt đầu dòng (có thể dùng khoảng trắng hoặc tab), khối lệnh kết thúc khi không thụt đầu dòng nữa.

Ví dụ:

1
2
3
4
if a == 5:
   print('a bằng 5 đấy nhé')
# comment thì quăng hết vào đây
print('Tới đây thì hết if rồi nhé')

Chỉ cần nắm được quy tắc này thì bạn đã có thể đọc được code Python vô tư rồi. Cũng chính vì kiểu cú pháp không phân chia khối lệnh một cách rõ ràng (tất nhiên là chỉ đối với những ai đã quen với các ngôn ngữ C-like mới thấy vậy) nên nhiều người cho rằng Python khó học, khó đọc. Nhưng thật ra chỉ cần nắm được đặc thù cú pháp này, bạn sẽ thấy Python là một ngôn ngữ cực kì dễ học, dễ đọc, thậm chí cú pháp như vậy có phần “đẹp” nữa ấy chứ =))

Bạn cũng cần chú ý đến việc thụt đầu dòng này, vì nếu khi viết chương trình mà thụt thò bậy bạ, nhẹ thì nó ném lỗi vào mặt, còn nặng thì nó sai logic là đi tong cả ngày làm việc để debug chứ chả đùa đc đâu.

Đến đây, bạn đã nắm được những điểm khác biệt cơ bản giữa Python và các ngôn ngữ lập trình khác, quan trọng nhất là về mặt cú pháp. Ít nhiều thì từ bây giờ bạn cũng có thể dễ dàng đọc được các đoạn chương trình Python rồi.

Hãy thử bắt đầu làm quen với Python bằng việc đọc hiểu và viết lại các đoạn chương trình đơn giản trong link sau: https://wiki.python.org/moin/SimplePrograms

Ở bài tiếp theo, chúng ta sẽ cùng đi vào tìm hiểu các kiểu dữ liệu, các khối lệnh, toán tử,… trong Python.

Advertisements
By votinh33 Posted in Không phân loại

Bài 2: Giới thiệu Flask và Jinja2

Ở phần 2 của Bài 2 này, chúng ta sẽ tìm hiểu sơ qua một chút về Flask và Jinja2. Đây là 2 thành phần chính để build 1 website. Ngoài ra cũng còn khá nhiều các libs khác mà nói chung là không có cũng không sao, được cái là mang cực vào thân. :)

1. Flask là gì?

Như tiêu đề của khóa học – “Làm website bằng Python và Flask” cho nên không biết về Flask thì không xong. Như vậy, Flask là gì? Trước tiên, Flask là Open Source, nghĩa là bạn có thể thoải mái sử dụng, ứng dụng, hoặc thay đổi nó mà không phải lo lắng suy nghĩ gì về vấn đề bản quyền. Tiếp theo, Flask là một Micro Framework dành cho Python, dựa trên 2 utility libraries là Werkzeug, Jinja 2. Dựa trên 2 libraries chính này mà Flask đã xây dựng nên 1 micro framework với cấu trúc và cách viết cực kỳ đơn giản, dễ tiếp cận, dễ làm quen, dễ đọc, dễ hiểu,… Giới thiệu sơ thôi, giờ vào luôn vấn đề, các bạn thử đọc xem 1 đoạn code đơn giản nhưng kinh điển dưới đây.

Sample code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Import  Flask để sử dụng, Flask sẽ được gọi từ site-packages trong thư mục cài python của bạn
    from flask import Flask
    
    # Khởi tạo 1 ứng dụng Flask
    app = Flask(__name__)
    
    # Khai báo 1 đường dẫn (route) và nội dung trả về (html, json, xml,..)
    @app.route("/")
    def hello():
        return "Hello World!"
    
    # Khởi chạy ứng dụng, bắt buộc phải có, nó sẽ chạy đầu tiên khi run application
    if __name__ == "__main__":
        app.run()
   

Xong, giờ chỉ cần run cái app và truy cập đến cái route đã khai báo thì bạn đã có thể nói lời chào với thế giới bằng Flask. Rất ngắn gọn, đơn giản phải không.

2. Jinja2 là gì?

Jinja2 là một templates engine. Nó giống như là Razor view trong ASP.NET MVC hay Twig, Smarty trong PHP. Là một extensions hỗ trợ cho việc show dữ liệu từ app ra html. Jinja2 là 1 extension được kèm theo Flask nên sau khi cài đặt Flask, bạn có thể sử dụng luôn Jinja2 mà không cần phải cài thêm.

Code sample:

Flask:

1
2
3
4
5
6
# Khai báo 1 đường dẫn
    @app.route("/")
    def hello():
        # Function này sẽ render page sample.html và kèm theo là 2 dữ liệu foo, bar (2 dữ liệu này sẽ show ra html)
        return render_template("sample.html", foo=foo_string, bar=bar_array)
   

HTML: sample với Foo là string và Bar là array

1
2
3
4
5
6
7
8
9
10
11
12
13
<div>
  <!-- Sử dụng cặp dấu '{{' và '}}' để truy cập 1 biến đơn -->
  Foo value:
  <p>
    {{ foo_string }}  
  </p
  <!-- Sử dụng cặp dấu '{%' và '%}' để viết 1 đoạn code python -->
  {% for bar in bar_array %}
  <p>
    {{ bar }}   
  </p>
  {% endfor %} 
</div>

Các thông số mặc định của Jinja2 khi cài đặt Flask

  • Jinja2 được sử dụng trên các page có định dạng: .html , .htm , .xml và .xhtml.
  • Flask đưa vào một số function global và helper trong Jinja2 để có thể sử dụng các mã Python trên các template.

Các biến global sau được mặc định có thể sử dụng trong Jinja2

  • config Cấu hình hiện tại của app (flask.config)
  • request Lấy request hiện tại (flask.request). Biến này sẽ vô hiệu nếu template (html) đã được render mà không có request.
  • session Lấy session hiện tại (flask.session). Biến này sẽ vô hiệu nếu template (html) đã được render mà không có request.
  • g Lấy các request global mặc định (flask.g). Biến này sẽ vô hiệu nếu template (html) đã được render mà không có request.
  • url_for() Convert đường dẫn đến file (css, js, html,…) thành đường dẫn trên host.
  • get_flashed_messages() Passing các giá trị được đặt trong hàm flash() ra html.

Ngoài ra còn có các khái niệm khác như: autoescape, template_filter, context_processor,… Mà chúng ta sẽ làm quen trong các bài học tiếp theo.

By votinh33 Posted in Không phân loại

Giới thiệu Python

Giới thiệu Python

Python là một ngôn ngữ lập trình năng động với nhiều tính năng được sử dụng trong một loạt các ứng dụng. Python thường được so sánh với Tcl, Perl, Ruby, Scheme, hoặc Java. Một vài tính năng đặc trưng của nó gồm:

  • cú pháp rất trong sáng, dễ đọc
  • các khả năng tự xét (introspection) mạnh mẽ
  • hướng đối tượng trực giác
  • cách thể hiện tự nhiên mã thủ tục (procedural code)
  • hoàn toàn mô-đun hóa, hỗ trợ các gói theo cấp bậc
  • xử lý lỗi dựa theo ngoại lệ (exception)
  • kiểu dữ liệu động ở mức rất cao
  • các thư viện chuẩn và các mô-đun ngoài bao quát hầu như mọi việc
  • phần mở rộng và mô-đun dễ dàng viết trong C, C++ (hoặc Java cho Jython, hoặc các ngôn ngữ .NET cho IronPython)
  • có thể nhúng trong ứng dụng như một scripting interface

Python mạnh… và nhanh

Những người hâm mộ Python dùng câu “kèm theo pin” để nói đến bộ thư viện chuẩn, trong đó chứa mọi thứ từ việc xử lý không đồng bộ cho tới các tập tin ZIP. Bản thân ngôn ngữ là một nhà máy linh động có thể giải quyết hầu hết mọi vấn đề. Viết máy chủ web cho riêng bạn với ba dòng mã. Viết mã theo hướng dữ liệu với khả năng tự xét mạnh mẽ và khả chuyển và những tính năng như siêu lớp (meta-classes), kiểu vịt (duck typing) và trang hoàng (decorators) của Python.

Python giúp bạn viết mã bạn cần, thật nhanh. Và, nhờ vào trình biên dịch đã được tối ưu hóa, và những thư viện hỗ trợ, mã Python chạy nhanh hơn đa số các ứng dụng cần.

Python hòa hợp tốt với các thứ khác

Python có thể kết nối với các đối tượng COM, .NET, và CORBA.

Với những thư viện Java, sử dụng Jython, một cài đặt của Python cho máy ảo Java.

Với .NET, thử IronPython, cài đặt Python mới của Microsoft cho .NET, hoặc Python for .NET.

Python cũng được hỗ trợ bởi Internet Communications Engine (ICE) và nhiều công nghệ kết nối khác.

Nếu bạn nhận ra một vài điều Python không thể làm, hoặc nếu bạn cần sự thực thi nhanh của mã mức thấp, bạn có thể viết mô-đun mở rộng trong C hoặc C++, hoặc gói mã đang có bằng SWIG hoặc Boost.Python. Các mô-đun đã gói được sử dụng y như những mô-đun Python. Người ta gọi là kết nối ngôn ngữ đã giản đơn. Bạn cũng có thể đi đường ngược lại và nhúng Python vào ứng dụng của bạn, đem lại cho người dùng ngôn ngữ mà họ sẽ say mê.

Python chạy khắp nơi

Python có cho mọi hệ điều hành: Windows, Linux/Unix, OS/2, Mac, Amiga, và những hệ khác. Thậm chí có cả những phiên bản chạy trên .NET, máy ảo Java, và điện thoại di động Nokia Series 60. Bạn sẽ rất hài lòng khi biết rằng cùng một mã nguồn sẽ chạy không khác nhau trên mọi cài đặt.

Hệ thống của bạn không có trong danh sách ở đây? Không sao, nó vẫn có thể chạy Python được nếu có một trình biên dịch C trên hệ thống. Hỏi ở news:comp.lang.python – hoặc cứ thử tự biên dịch Python lại.

Python gần gũi… và dễ học

Nhóm tin Python được biết đến như là một trong những nhóm thân thiện nhất. Cộng đồng nhà phát triển và người dùng mở một wiki, chủ trì các hội thảo quốc tế và địa phương, đứng lớp dạy phát triển, và đóng góp vào kho lưu trữ mã trực tuyến.

Python cũng có kho tài liệu đầy đủ, vừa tồn tại trong bản thân ngôn ngữ lẫn trên mạng. Những tài liệu trên mạng nhắm vào cả lập trình viên chuyên nghiệp lẫn người mới. Tất cả đều được thiết kế nhằm giúp bạn sản xuất nhanh hơn. Và sự có mặt của những quyển sách làm quá trình học tập đầy đủ hơn.

Python mở

Cài đặt Python dùng giấy phép nguồn mở nên được sử dụng và phân tối tự do, ngay cả trong việc thương mại. Giấy phép Python được quán xuyến bởi Python Software Foundation.

Trích từ http://codedaily.vn/2014/12/gioi-thieu-python/

 

By votinh33 Posted in IT

Java – Tìm hiểu về Reflection (Runtime Type Information)

Java Reflection APIReflection là kĩ thuật rất cần thiết để lấy các thông tin của một kiểu dữ liệu. Dựa vào đó ta có thể kích hoạt (như các phương thức) hoặc tạo thể hiện của kiểu dữ liệu đó. Một ứng dụng quan trọng của reflection mà bạn có thể biết là Java Bean. Nhờ đó, các IDE (như NetBeans) có thể lấy được các thông tin và thiết lập giá trị cho các đối tượng.

Kiến trúc của Java Reflection API

Các lớp được dùng trong reflection nằm trong hai package là java.langjava.lang.reflect. Package java.lang.reflect bao gồm ba lớp chính mà bạn cần biết là Constructor, Field và Method:

–      Class<T>: lớp này đại diện cho các lớp, interface và chứa các phương thức dùng để lấy các đối tượng kiểu Constructor, Field, Method,…

–      AccessibleObject: các kiểm tra về phạm vi truy xuất (public, private, protected) của field, method, constructor sẽ được bỏ qua. Nhờ đó bạn có thể dùng reflection để thay đổi, thực thi các thành phần này mà không cần quan tâm đến phạm vi truy xuất của nó.

–      Constructor: chứa các thông tin về một constructor của lớp.

–      Field: chứa các thông tin về một field của lớp, interface.

–      Method: chứa các thông tin về một phương thức của lớp, interface.

Java Reflection API

Tạo đối tượng Class<>

Đối tượng kiểu này được tạo ra bằng cách sử dụng phương thức static  Class.forName():

1
2
3
4
5
6
7
8
try {
    Class c =  Class.forName("yinyang.Foo");
    // ...
}
catch (ClassNotFoundException e) {
    System.err.println(e);
}

Trong trường hợp không tìm thấy lớp tương ứng, phương thức trên sẽ ném ra ngoại lệ ClassNotFoundException. Điều này có thể bất tiện vì bạn phải sử dụng try catch hoặc ném ngoại lệ này khỏi phương thức.

Vậy bạn có thể dùng cách khác với từ class (class literal), cách này đảm bảo rằng lớp được sử dụng luôn luôn tồn tại và không có ngoại lệ nào xảy ra:

1
2
Class c1 = Foo.class;
Class c2 = int.class; // equivalent to Integer.class;

Đối với các kiểu dữ liệu nguyên thủy như void, int, boolean, char,… bạn có thể dùng field TYPE để lấy được đối tượng Class tương ứng, tuy nhiên bạn cần viết đúng tên lớp. Như vậy các dòng lệnh sau cho ra kết quả tương tự nhau:

1
2
3
Class c1 = int.class;
Class c2 = Integer.class;
Class c3 = Integer.TYPE;

Sau đây là một ví dụ đơn giản dùng reflection để in ra các thông tin của lớp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package yinyang;
import java.lang.reflect.Method;
public class Foo {
    static void Test() throws ClassNotFoundException
    {
        Class c = Class.forName("yinyang.Foo");
        System.out.println("Name: "+c.getName());
        System.out.println("Simple Name: "+c.getSimpleName());
        System.out.println("Declared Methods:");
        for(Method m:c.getDeclaredMethods())
            System.out.println("-"+m);
    }
    public static void main(String[] args)
    {
        try {
            Test();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Output:

Name: yinyang.Foo

Simple Name: Foo

Declared Methods:

-public static void yinyang.Foo.main(java.lang.String[])

-static void yinyang.Foo.Test() throws java.lang.ClassNotFoundException

Lấy và gán giá trị cho field

Để truy xuất đến một thành viên của lớp nói chung (field, method,…), bạn chỉ cần lấy được đối tượng đại diện tương ứng thông qua các phương thức của Class. Sau đó sử dụng các phương thức của đối tượng đại diện để thao tác.

Trong ví dụ này, ta sẽ sử dụng hai phương thức:

–      Class.getField(String name): trả về một đối tượng Field.

–      Field.set(Object obj, Object value): gán value cho field tương ứng của đối tượng obj. Bạn có thể thay thế phương thức này bằng các phương thức setXXX() cho mỗi kiểu dữ liệu cụ thể (setInt, setBoolean, setChar,…).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.lang.reflect.Field;
public class Foo {
    public int myField=0;
    public static void main(String args[])
    {
        try {
            Foo foo=new Foo();
            System.out.println("Default value: "+foo.myField);
            Class c = Class.forName("Foo");
            Field f=c.getField("myField");
            f.set(foo, 100);
            System.out.println("After changing: " +foo.myField);
        }
        catch (Throwable e) {
            e.printStackTrace();
        }
    }
}

Output:

Default value: 0

After changing: 100

Đối với các thành viên private, bạn có thể xem ở phần cuối bài.

Thực thi một phương thức

Để kích hoạt một phương thức cụ thể, bạn cần sử dụng hai phương thức instance sau:

–      Class.getMethod(String name, Class[] parameterTypes): trả về đối tượng Method đại diện cho một phương thức của lớp. Phương thức này được xác định qua tên và các kiểu tham số.

–      Method.invoke(Object obj, Object[] args) thực thi phương thức tương ứng của đối tượng obj với các tham số args.

Ví dụ sau thực thi phương thức add(int a,int b) của lớp Foo bằng cách tạo một đối tượng Foo và truyền vào làm tham số đầu tiên trong phương thức Method.invoke(). Nếu phương thức add() là static, bạn chỉ cần truyền null vào làm tham số đầu tiên của phương thức Method.invoke().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.lang.reflect.Method;
public class Foo {
     public int add(int a,int b)
     {
        return a+b;
     }
     public static void main(String args[])
     {
        try {
          Class c = Class.forName("Foo");
           Method method = c.getMethod("add",int.class,int.class);
           Object ret= method.invoke(new Foo(), 3,5);
           System.out.println("3+5="+ret);
        }
        catch (Throwable e) {
           e.printStackTrace();
        }
     }
}

Output:

3+5=8

Tạo thể hiện của lớp

Có hai phương thức để tạo một thể hiện của lớp:

–      Class.newInstance(): tạo một đối tượng với constructor không có tham số.

–      Constructor. newInstance(Object[] initargs): tạo đối tượng với constructor có tham số.

Ví dụ:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.lang.reflect.Constructor;
public class Foo {
    public Foo(){
        System.out.println("inside Foo()");
    }
    public Foo(String text){
        System.out.println("inside Foo(String): "+text);
    }
     public static void main(String args[])
     {
        try {
           Class c = Class.forName("Foo");
           // parameterless constructor
           Object foo1=c.newInstance();
           // parametrized constructor
           Constructor con=c.getConstructor(String.class);
           Object foo2=con.newInstance("Hello");
        }
        catch (Throwable e) {
           e.printStackTrace();
        }
     }
}

Output:

inside Foo()

inside Foo(String): Hello

Lưu ý

–      Bởi vì Class là một lớp generic, bạn có thể dùng kí tự wildcard để xác định kiểu dữ liệu mà nó đại diện:

Class<?> c1=int.class;

Class<? extends Number> c2 = int.class;

–      Đối với các thành viên không public, bạn có thể lấy được các đối tượng đại diện của chúng (constructor, field, method) bằng các phương thức getDeclaredXXX().

By votinh33 Posted in IT