Định dạng chuỗi tham số có tên?


134

Tôi biết đó là một câu hỏi thực sự đơn giản, nhưng tôi không biết làm thế nào để google nó.

làm thế nào tôi có thể làm được

print '<a href="%s">%s</a>' % (my_url)

Vì vậy, my_urlđược sử dụng hai lần? Tôi giả sử tôi phải "đặt tên" %svà sau đó sử dụng một dict trong params, nhưng tôi không chắc chắn về cú pháp thích hợp?


chỉ là FYI, tôi biết tôi chỉ có thể sử dụng my_urlhai lần trong các thông số, nhưng đó không phải là vấn đề :)


Tiêu đề của câu hỏi là một chút sai lệch. Điều này không liên quan gì đến câu lệnh in, chỉ với cách hoạt động của phép nội suy chuỗi.
Greg Ball

Khi bạn không biết làm thế nào để google nó, hãy vào đây để sử dụng tìm kiếm: python.org/doc . Nó tốt hơn Google vì một lý do quan trọng.
S.Lott

Câu trả lời:


79

Trong Python 2.6+ và Python 3, bạn có thể chọn sử dụng phương thức định dạng chuỗi mới hơn.

print('<a href="{0}">{0}</a>'.format(my_url))

giúp bạn không lặp lại đối số, hoặc

print('<a href="{url}">{url}</a>'.format(url=my_url))

nếu bạn muốn đặt tên tham số.

print('<a href="{}">{}</a>'.format(my_url, my_url))

đó là vị trí nghiêm ngặt và chỉ đi kèm với cảnh báo rằng các đối số định dạng () tuân theo các quy tắc Python trong đó các đối số không tên phải xuất hiện trước, theo sau là các đối số được đặt tên, theo sau là * args (một chuỗi như danh sách hoặc tuple) và sau đó là * kwargs (một lệnh chính tả khóa với chuỗi nếu bạn biết những gì tốt cho bạn). Các điểm nội suy được xác định trước bằng cách thay thế các giá trị được đặt tên ở nhãn của chúng và sau đó là vị trí từ những gì còn lại. Vì vậy, bạn cũng có thể làm điều này ...

print('<a href="{not_my_url}">{}</a>'.format(my_url, my_url, not_my_url=her_url))

Nhưng không phải ...

print('<a href="{not_my_url}">{}</a>'.format(my_url, not_my_url=her_url, my_url))

Thật tuyệt khi thấy sự thay đổi ảnh hưởng từ ++ sang #
cod3monk3y

3
Phương thức trên không dành cho định dạng chuỗi được đặt tên , đây là định dạng chuỗi vị trí. Vì vậy, điều này không thực sự trả lời câu hỏi.
jaapz

Các "literal {arg1}".format(arg1="arg!")định dạng tên làm việc với Python 3.5, trong khi terser f"literal {arg1}"là một sự đổi mới mới hơn trong Python 3.6 hoặc mới hơn, AFAIK.
MarkHu

218
print '<a href="%(url)s">%(url)s</a>' % {'url': my_url}

3
Tôi thích tạo ra dict với kwargs:'<a href="%(url)s">%(url)s</a>' % dict(url=my_url)
schlamar

11
Tôi tự hỏi tại sao bạn thích schmlamar đó? Tôi sẽ không biết điều đó có nghĩa gì, so sánh với tuyên bố bình thường của một lệnh mà OP sử dụng ...
GreenAsJade

1
Các tài liệu hướng dẫn không nói khi điều này đã được giới thiệu, vì vậy nó có thể là trong tất cả các Python 2 phiên bản.
Evgeni Sergeev

2
Sử dụng định dạng () nếu bạn có thể, nó hoạt động tốt hơn và ở nhiều nơi hơn. Sử dụng% nếu bạn PHẢI.
uchuugaka

39

Giải pháp trong Python 3.6+

Python 3.6 giới thiệu định dạng chuỗi ký tự , để bạn có thể định dạng các tham số đã đặt tên mà không lặp lại bất kỳ tham số đã đặt tên nào bên ngoài chuỗi:

print(f'<a href="{my_url:s}">{my_url:s}</a>')

Điều này sẽ đánh giá my_url, vì vậy nếu nó không được xác định, bạn sẽ nhận được một NameError. Trong thực tế, thay vì my_url, bạn có thể viết một biểu thức Python tùy ý, miễn là nó ước tính thành một chuỗi (vì :smã định dạng). Nếu bạn muốn một biểu diễn chuỗi cho kết quả của một biểu thức có thể không phải là một chuỗi, hãy thay thế :sbằng !s, giống như với định dạng chuỗi thông thường, trước bằng chữ.

Để biết chi tiết về định dạng chuỗi ký tự, xem PEP 498 , nơi nó được giới thiệu lần đầu tiên.


1
PEP đó dường như không bao gồm tất cả các trình định dạng; Tôi nghĩ rằng họ giống như str.format được ghi nhận ở đây: docs.python.org/3.4/library/string.html#formatstrings
mpen

6

Bạn sẽ nghiện cú pháp.

Ngoài ra C # 6.0, các nhà phát triển EcmaScript cũng đã biết đến cú pháp này.

In [1]: print '{firstname} {lastname}'.format(firstname='Mehmet', lastname='Ağa')
Mehmet Ağa

In [2]: print '{firstname} {lastname}'.format(**dict(firstname='Mehmet', lastname='Ağa'))
Mehmet Ağa

5

Để xây dựng các trang HTML, bạn muốn sử dụng một công cụ tạo khuôn mẫu, không phải là phép nội suy chuỗi đơn giản.


2
Công cụ tạo khuôn mẫu của Django cũng có thể chứng minh là công cụ lý tưởng cho các email bạn đang thực hiện.
Mike Graham

6
Điều gì ngăn bạn sử dụng mẫu Django để tạo phần thân email với render()phương thức của nó ? Không có gì nói rằng bạn phải cung cấp đầu ra mẫu cho HttpResponse(). Django là linh hoạt đáng xấu hổ .
Mike DeSimone

1
@Mike: Tôi nghĩ Django cũng có thể có một giải pháp cho vấn đề này, nhưng tôi chưa tìm thấy nó: p Tôi có thể sẽ chuyển email của mình thành các mẫu rồi! Cảm ơn. Có thể tôi đã bị trêu chọc, nhưng tôi thấy nó khá cứng nhắc ở một số khu vực.
mở

2
@random những người đọc những bình luận này: tìm thấy chi tiết hơn về cách thực hiện điều đó tại đây rossp.org/blog/2006/jul/11/seinating-e-mails-temsheet
mpen

1
Để bình luận về câu hỏi, bạn muốn sử dụng ý kiến, không phải câu trả lời.
suriv

2

Cũng như cách từ điển, có thể hữu ích khi biết định dạng sau:

print '<a href="%s">%s</a>' % (my_url, my_url)

Ở đây, nó là một thứ dư thừa và cách từ điển chắc chắn ít bị lỗi hơn khi sửa đổi mã, nhưng vẫn có thể sử dụng các bộ dữ liệu cho nhiều lần chèn. Phần đầu tiên %sđược thay thế cho phần tử thứ nhất trong bộ dữ liệu, phần thứ hai %sđược thay thế cho phần tử thứ hai trong bộ dữ liệu, và cứ như vậy cho mỗi phần tử trong bộ dữ liệu.


Tôi chỉ nói với một anh chàng vì đã gợi ý điều này :) Anh ấy xóa bài viết của mình. Tôi cảm thấy tồi tệ bây giờ. Vâng, tôi biết tôi có thể làm điều này, nhưng đó không phải là điều tôi đang tìm kiếm. Như bạn đã nói, nó là dư thừa và my_urlthực sự là một lời gọi hàm mà tôi không muốn phải đánh giá hai lần. Hai lần không tệ lắm, nhưng nó có thể dễ dàng gấp 20 lần :)
mpen

5
Tôi hình dung tôi sẽ giữ của tôi, chỉ trong trường hợp nó giúp được người khác. Cách từ điển có thể là cách tốt nhất để đi. Nhưng để dự phòng, (get_my_url(), )*20chỉ gọi hàm một lần và nhân đôi nó 20 lần.
Ponkadoodle
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.