2012-04-15 40 views
5

Gần đây, tôi thấy chức năng ''.format rất hữu ích vì nó có thể cải thiện khả năng đọc rất nhiều so với định dạng %. Đang cố gắng để đạt được định dạng chuỗi đơn giản:Chức năng ".format" của python

data = {'year':2012, 'month':'april', 'location': 'q2dm1'} 

year = 2012 
month = 'april' 
location = 'q2dm1' 
a = "year: {year}, month: {month}, location: {location}" 
print a.format(data) 
print a.format(year=year, month=month, location=location) 
print a.format(year, month, location) 

Trong khi hai bản in đầu tiên làm định dạng như tôi mong đợi (vâng, something=something trông xấu xí, nhưng đó là chỉ là ví dụ), người cuối cùng sẽ tăng KeyError: 'year'. Có bất kỳ mẹo nào trong python để tạo từ điển để nó tự động điền các khóa và giá trị, ví dụ somefunc(year, month, location) sẽ xuất ra {'year':year, 'month': month, 'location': location}?

Tôi khá mới với python và không thể tìm thấy bất kỳ thông tin nào về chủ đề này, tuy nhiên một mẹo như thế này sẽ cải thiện và thu hẹp mã hiện tại của tôi một cách mạnh mẽ.

Cảm ơn trước và tha thứ cho tiếng Anh của tôi.

Trả lời

6

Đầu tiên print nên

print a.format(**data) 

Ngoài ra, nếu bạn đang tìm kiếm một số phím tắt, bạn có thể viết một mặt hàng như, không có sự khác biệt lớn.

def trans(year, month, location): 
    return dict(year=year, month=month, location=location) 
+0

Có vẻ như không có cách nào để thu nhỏ mã lặp lại này :) Chức năng là tốt và đó là những gì tôi đã làm, nhưng sau đó tôi thấy khó để duy trì vì rất nhiều lý lẽ tôi cần để thay đổi mã ở một vài nơi, hóa ra thậm chí còn tệ hơn là tạo ra dict bằng tay. –

+0

@duke_nukem có nó phụ thuộc vào cách sử dụng thực tế của bạn. Mã này là tốt và api định dạng là đủ rõ ràng. Nếu bạn muốn đạt được thứ gì đó như 'định dạng (* args, ** kwargs)', nó cũng có thể được thực hiện, nhưng tôi không nghĩ nó có thể làm mọi thứ dễ dàng hơn. – okm

1

Bạn có thể sử dụng dict() callable:

dict(year=yeah, month=month, location=location) 

Khi qua các đối số từ khóa nó tạo ra một dict có chứa các yếu tố bạn quy định như kwargs.

Nếu bạn không muốn xác định tên đối số, sử dụng phong cách vị trí của .format():

>>> a = 'year {0} month {1} location {2}' 
>>> print a.format(2012, 'april', 'abcd') 
year 2012 month april location abcd 

Tuy nhiên, nếu bạn cố gắng làm một cái gì đó tương tự như những gì compact() in PHP không (tạo ra một tên biến bản đồ dict để các giá trị của nó mà không chỉ định tên và biến riêng biệt), vui lòng không. Nó chỉ là kết quả trong mã không thể đọc được xấu xí và sẽ yêu cầu hacks khó chịu anyway.

+0

Vâng, tôi biết dict() nhưng tôi đang cố gắng tránh mã không cần thiết và thu nhỏ nó xuống một chút. .format có thể chấp nhận tùy chọn của bạn mà không có dict() bằng cách này. Cảm ơn bạn. –

+0

Cảm ơn, nó gần với những gì tôi cần, tuy nhiên với 10-12 đối số nó trở nên khá khó khăn để điều hướng thông qua các chỉ số. –

+0

Tốt trong trường hợp này, bạn có nghĩa vụ phải sử dụng cú pháp dict. Tuy nhiên, tùy thuộc vào những gì bạn muốn làm, hãy xem xét sử dụng một công cụ mẫu thực sự như [jinja2] (http://jinja.pocoo.org/). – ThiefMaster

1

Bạn có thể vượt qua locals():

a.format(**locals()) 

Tất nhiên, điều này có vấn đề: bạn sẽ phải vượt qua tất cả mọi thứ trong người dân địa phương, và nó có thể khó khăn để hiểu được tác động của việc đổi tên hoặc loại bỏ một biến .

Cách tốt hơn sẽ là:

a.format(**{k:v for k,v in locals() if k in ('year', 'month')}) 
# or; note that if you move the lambda expression elsewhere, you will get a different result 
a.format(**(lambda ld = locals(): {k:ld[k] for k in ('year', 'month')})()) 

Nhưng điều này không phải là bất kỳ súc tích hơn, trừ khi bạn quấn nó lên với một chức năng (mà phải đương nhiên phải mất một tham số dict).

3
data = {'year':2012, 'month':'april', 'location': 'q2dm1'} 
a = "year: {year}, month: {month}, location: {location}" 

print a.format(**data) 

.. là những gì bạn đang tìm kiếm. Nó có chức năng giống hệt nhau để thực hiện .format(year=data['year'], ...) hoặc các ví dụ khác mà bạn đã cung cấp.

Điều kép asterix là một điều khó tìm kiếm, vì vậy nó thường được gọi là "kwargs".Dưới đây là một good SO question on this syntax

0

Tính đến Python 3.6, bạn cũng có thể sử dụng mới Formatted string literals (f-strings), mà bạn có thể sử dụng với biến:

year = 2012 
month = 'april' 
location = 'q2dm1' 
a = f"year: {year}, month: {month}, location: {location}" 
print(a) 

hoặc một điển:

data = {'year': 2012, 'month': 'april', 'location': 'q2dm1'} 
a = f"year: {data['year']}, month: {data['month']}, location: {data['location']}" 
print(a) 

Lưu ý f tiền tố trước chuỗi ký tự.

PEP 498: Formatted string literals:

định dạng xâu được bắt đầu với 'f' và tương tự như các chuỗi định dạng được chấp nhận bởi str.format(). Chúng chứa các trường thay thế được bao quanh bởi các dấu ngoặc nhọn. Các lĩnh vực thay thế là biểu thức, trong đó được đánh giá tại thời gian chạy, và sau đó định dạng bằng định dạng() giao thức:

>>> 
>>> name = "Fred" 
>>> f"He said his name is {name}." 
'He said his name is Fred.' 
>>> width = 10 
>>> precision = 4 
>>> value = decimal.Decimal("12.34567") 
>>> f"result: {value:{width}.{precision}}" # nested fields 
'result:  12.35' 

...

Các vấn đề liên quan