Tại sao dấu ngoặc đơn trong bản in lại tự nguyện trong Python 2.7?


98

Trong Python 2.7, cả hai phần sau sẽ làm tương tự

print("Hello, World!") # Prints "Hello, World!"

print "Hello, World!" # Prints "Hello, World!"

Tuy nhiên sau đây sẽ không

print("Hello,", "World!") # Prints the tuple: ("Hello,", "World!")

print "Hello,", "World!" # Prints the words "Hello, World!"

Trong Python, dấu ngoặc đơn 3.x printlà bắt buộc, về cơ bản biến nó thành một hàm, nhưng trong 2.7 cả hai sẽ hoạt động với các kết quả khác nhau. Tôi nên biết thêm điều gì printtrong Python 2.7?


7
Trong Python, 2.x printthực sự là một câu lệnh đặc biệt, không phải là một hàm. Đây cũng là lý do tại sao nó không thể được sử dụng như: lambda x: print xLưu ý rằng (expr)không tạo Tuple (nó dẫn đến expr), nhưng ,có.

Tôi giả định sự ủng hộ cho việc in ấn như một chức năng và in như một tuyên bố là để duy trì tính tương thích ngược với các phiên bản cũ của python trong khi khuyến khích mọi người sử dụng cú pháp mới để di chuyển về phía python 3.
GWW

11
ps, Để kích hoạt chức năng in trong 2.7 (và không có hành vi tuyên bố in), bạn phải làm một nhập khẩu trong tương lai:from __future__ import print_function
Jeff Mercado

Trên thực tế, ví dụ thứ hai sẽ in "Hello, World!" (không có khoảng trắng) hoặc nó sẽ in "Hello, World!" (với khoảng trắng) như trong ví dụ.
kapad

Câu trả lời:


106

Trong Python, 2.x printthực sự là một câu lệnh đặc biệt và không phải là một hàm *.

Đây cũng là lý do tại sao nó không thể được sử dụng như: lambda x: print x

Lưu ý rằng (expr)không tạo Tuple (kết quả là expr), nhưng ,có. Điều này có thể dẫn đến sự nhầm lẫn giữa print (x)print (x, y)trong Python 2.7

(1)   # 1 -- no tuple Mister!
(1,)  # (1,)
(1,2) # (1, 2)
1,2   # 1 2 -- no tuple and no parenthesis :) [See below for print caveat.]

Tuy nhiên, vì printlà một câu lệnh cú pháp / cấu trúc ngữ pháp đặc biệt trong Python 2.x nên, không có dấu ngoặc, nó xử lý ,'s theo cách đặc biệt - và không tạo Tuple. Cách xử lý đặc biệt này của printcâu lệnh cho phép nó hoạt động khác đi nếu có dấu vết ,hoặc không.

Chúc bạn viết mã vui vẻ.


* printHành vi này trong Python 2 có thể được thay đổi thành hành vi của Python 3:

from __future__ import print_function

3
Cảm ơn vì (expr) != tuplelời giải thích :-)
Hubro

5

Tất cả đều rất đơn giản và không liên quan gì đến khả năng tương thích chuyển tiếp hoặc ngược lại.

Dạng chung cho printcâu lệnh trong tất cả các phiên bản Python trước phiên bản 3 là:

print expr1, expr2, ... exprn

(Mỗi biểu thức lần lượt được đánh giá, chuyển đổi thành một chuỗi và được hiển thị với khoảng cách giữa chúng.)

Nhưng hãy nhớ rằng việc đặt dấu ngoặc đơn xung quanh một biểu thức vẫn là một biểu thức giống nhau.

Vì vậy, bạn cũng có thể viết cái này là:

print (expr1), (expr2), ... (expr3)

Điều này không liên quan gì đến việc gọi một hàm.


Đây là một câu trả lời hoàn toàn chính xác, tôi cũng không chắc tại sao nó lại bị phản đối nhiều như vậy.
Martijn Pieters

Nó không phải print (expr1), (expr2), ... (expr3)là về lý do tại sao print (expr1, expr2, ... , expr3)nó lại hợp pháp trong python 2.x trong khi nó không phải theo tiêu chuẩn 2.x.
vinnief vào

5

Ở đây chúng tôi có tác dụng phụ thú vị khi nói đến UTF-8.

>> greek = dict( dog="σκύλος", cat="γάτα" )
>> print greek['dog'], greek['cat']
σκύλος γάτα
>> print (greek['dog'], greek['cat'])
('\xcf\x83\xce\xba\xcf\x8d\xce\xbb\xce\xbf\xcf\x82', '\xce\xb3\xce\xac\xcf\x84\xce\xb1')

Bản in cuối cùng là bộ giá trị byte thập lục phân.


7
Tôi cho rằng đó là bởi vì bản in in đúng UTF-8, nhưng khi nó nhận được một tuple, như bản in cuối cùng của bạn, nó sẽ chạy reprtrên đó, tại thời điểm đó nó có thể mã hóa tất cả các chuỗi trong dict thành ASCII.
Hubro

3
@Codemonkey, bạn nói đúng về repr . Bạn đã sai về ASCII. ASCII là mã hóa mặc định cho Python. Nhưng tôi có ở đầu tập lệnh Python #encoding=utf-8, linux env LANG=en_US.UTF-8. Vì vậy, mã hóa repr không sử dụng ASCII mặc định, mà mã hóa utf-8.
Karlo Smid

1
Repr mã hóa strbằng string_escapemã hóa đặc biệt . Chuỗi đã được mã hóa unicode thành UTF-8.
tzot

@KarloSmid: Ý tôi muốn nói là reprcó lẽ cần thực hiện các bước để đảm bảo rằng văn bản có thể được biểu diễn bằng ASCII (bằng cách thoát các ký hiệu không phải ASCII), không nhất thiết là chuỗi được mã hóa dưới dạng ASCII. Tôi vẫn không biết liệu điều đó có hoàn toàn chính xác hay không.
Hubro

Tất cả các vùng chứa Python (danh sách, dict, tuple, set) bao gồm nội dung của chúng dưới dạng repr()đầu ra khi được chuyển đổi thành một chuỗi (chúng không triển khai __str__, chỉ __repr__). Những gì bạn thấy không phải là đặc biệt đối với UTF-8; các repr()của một chuỗi cung cấp cho bạn Python xâu hợp lệ mà là ASCII-an toàn.
Martijn Pieters

2

Về cơ bản trong Python trước Python 3, print là một câu lệnh đặc biệt in tất cả các chuỗi nếu có dưới dạng đối số. Vì vậy, print "foo","bar"đơn giản có nghĩa là "in" foo "theo sau là" thanh ". Vấn đề với điều đó là nó rất hấp dẫn để hoạt động như thể print là một hàm, và ngữ pháp Python không rõ ràng về điều đó, vì (a,b)là một bộ tuple chứa abnhưng foo(a,b)là một lệnh gọi hàm của hai đối số.

Vì vậy, họ đã thực hiện thay đổi không tương thích cho 3 để làm cho các chương trình ít mơ hồ hơn và đều đặn hơn.

(Trên thực tế, tôi nghĩ 2,7 hoạt động như 2,6 đã làm về điều này, nhưng tôi không chắc chắn.)


Không, nó không "hấp dẫn" khi sử dụng nó như một chức năng. :) Tuy nhiên, không thể sử dụng nó như một hàm, vì vậy bạn không thể thực hiện [print x for x in alist] chẳng hạn.
Lennart Regebro
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.