2012-08-01 25 views
35

Có bất kỳ bất lợi, cảnh báo hoặc cảnh báo thực hành xấu về việc sử dụng mẫu sau không?Sử dụng phương thức locals() và format() cho chuỗi: có bất kỳ cảnh báo nào không?

def buildString(user, name = 'john', age=22): 
    userId = user.getUserId() 
    return "Name: {name}, age: {age}, userid:{userId}".format(**locals()) 

Tôi đã có một thế hệ mã chuỗi rất lặp đi lặp lại để viết và được cám dỗ để sử dụng này, nhưng một cái gì đó về việc sử dụng locals() khiến tôi khó chịu. Có bất kỳ nguy cơ về hành vi bất ngờ trong việc này không?

Edit: bối cảnh

tôi thấy mình liên tục viết những thứ như:

"{name} {age} {userId} {etc}...".format(name=name, age=age, userId=userId, etc=etc) 
+1

Tôi không thấy bất cứ điều gì khủng khiếp sai với nó ... – mgilson

+2

Bí quyết tuyệt vời thực sự! –

+2

Liên quan chặt chẽ đến http://stackoverflow.com/q/1550479/125507 – endolith

Trả lời

8

Hiện tại, có một cách chính thức để thực hiện việc này, như của Python 3.6.0: formatted string literals.

Nó hoạt động như thế này:

f'normal string text {local_variable_name}' 

Ví dụ: thay vì những:

"hello %(name)s you are %(age)s years old" % locals() 
"hello {name}s you are {age}s years old".format(**locals()) 

chỉ làm điều này:

f"hello {name}s you are {age}s years old" 

Dưới đây là ví dụ chính 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' 

tham khảo:

26

Nếu chuỗi định dạng không phải là người dùng cung cấp, sử dụng này là ổn.

format được ưu tiên so với sử dụng số % cũ để thay thế chuỗi.
locals được tích hợp sẵn với Python và hành vi của nó sẽ đáng tin cậy.

Tôi nghĩ locals thực hiện chính xác những gì bạn cần.
Chỉ cần không sửa đổi từ điển từ người dân địa phương và tôi sẽ nói bạn có một giải pháp khá tốt.

Nếu chuỗi định dạng do người dùng cung cấp, bạn có thể dễ bị tấn công do tiêm tất cả các loại lỗi.

+3

Không nên có một cảnh báo rằng chuỗi không bao giờ được ** do người dùng cung cấp **? Điều đó có thể mở ra quyền truy cập vào nội dung của mọi biến cục bộ. –

+0

Chụp thẳng @ BobStein-VisiBone, tôi đã cập nhật câu trả lời của mình. –

+0

Dường như có một chi phí hoạt động rất nhỏ sử dụng người dân địa phương() thay vì chỉ các biến bạn cần, vì bạn có một cuộc gọi chức năng bổ sung và bạn đang xây dựng một từ điển lớn hơn. Nó có thể không đáng kể đối với hầu hết các ứng dụng mặc dù: Tôi thấy sự khác biệt khoảng 2% trong một trường hợp kiểm tra nhanh. – Widjet

8

Tôi thường xuyên làm việc này. Vấn đề duy nhất tôi có là PyFlakes will complain about unused variables khi tôi làm điều đó.

+7

Không nếu bạn áp dụng https://github.com/kevinw/pyflakes/commit/1e36a5331100a1ddfb8899fd20359844aca4492c – iElectric

0

này rất cũ, nhưng nếu bạn thấy mình sử dụng .format một caveat tôi đã gặp với đi qua trong **locals là nếu bạn không có mà biến được định nghĩa bất cứ nơi nào, nó sẽ phá vỡ . Nói rõ những biến nào được truyền vào sẽ tránh điều này trong hầu hết các IDE hiện đại.

foo = "bar" 
"{foo} and {baz} are pair programming".format(**locals) 
<exception occurs> 
Các vấn đề liên quan