2009-10-11 35 views
9
def isBig(x): 
    if x > 4: 
     return 'apple' 
    else: 
     return 'orange' 

này hoạt động:Cách gán một biến trong IF và sau đó trả về biến đó. (Python)

if isBig(y): return isBig(y) 

này không làm việc:

if fruit = isBig(y): return fruit 

Tại sao không phải là lần thứ 2 một công việc !? Tôi muốn có 1 lớp lót. Ngoại trừ, cái đầu tiên sẽ gọi hàm TWICE.

Làm thế nào để làm cho nó 1 lót, mà không cần gọi hàm hai lần?

+6

Tại sao bạn muốn một lớp lót? Các chương trình không tốt hơn vì chúng có ít dòng hơn. –

+0

Giống như http://stackoverflow.com/questions/1513436/what-should-i-use-instead-of-assignment-in-an-expression-in-python/1513987#1513987 – PaulMcG

+2

Bạn có 100 trong số này? Bạn sẽ không xảy ra được viết một phân tích cú pháp, phải không? Xem danh sách này (http://nedbatchelder.com/text/python-parsers.html) từ trang web của Ned Batchelder. – PaulMcG

Trả lời

16

tôi thấy người khác đã chỉ ra tuổi của tôi "gán và thiết lập" Cookbook công thức, mà tóm lại trong phiên bản đơn giản nhất để:

class Holder(object): 
    def set(self, value): 
    self.value = value 
    return value 
    def get(self): 
    return self.value 

h = Holder() 

... 

if h.set(isBig(y)): return h.get() 

Tuy nhiên, điều này đã được dự định chủ yếu để giảm bớt phiên giữa Python và ngôn ngữ mà bài tập được hỗ trợ trực tiếp trong if hoặc while.Nếu bạn có "hàng trăm" như vậy check-and-trở lại trong một thác, đó là nhiều tốt hơn để làm điều gì đó hoàn toàn khác nhau:

hundreds = isBig, isSmall, isJuicy, isBlah, ... 

for predicate in hundreds: 
    result = predicate(y) 
    if result: return result 

hoặc thậm chí một cái gì đó giống như

return next(x for x in (f(y) for f in hundreds) if x) 

nếu nó OK để nhận ngoại lệ StopIteration nếu không có biến vị ngữ nào được thỏa mãn hoặc

return next((x for x in (f(y) for f in hundreds) if x)), None) 

nếu None là giá trị trả về thích hợp khi không có vị từ được thỏa mãn , v.v.

Hầu như không thay đổi, sử dụng (hoặc thậm chí mong muốn ;-) mẹo/non-idiom là một "mùi thiết kế" cho thấy tìm kiếm một cách tiếp cận khác biệt hơn và Pythonic - trường hợp Holder là chính xác là trường hợp đặc biệt mà tôi đã thiết kế nó, ví dụ, trường hợp bạn muốn giữ sự tương ứng chặt chẽ giữa mã Python và một số không Python (bạn đang chuyển ngữ một thuật toán tham chiếu trong Python và muốn nó hoạt động trước khi refactoring nó vào một hình thức Pythonic hơn, hoặc bạn đang viết Python như là một mẫu thử nghiệm sẽ được chuyển thành C++, C#, Java, vv, một khi nó hoạt động hiệu quả).

0

này không hoạt động do thiết kế ngôn ngữ cố ý, nhưng bạn có thể sử dụng this trick để có được xung quanh quyết định này

0

Vấn đề là các hoạt động chuyển nhượng không thể được đánh giá là có giá trị boolean. Tuyên bố if dựa vào việc có thể đánh giá một boolean. Ví dụ:

>>> fruit = 'apple' 
>>> bool(fruit = 'apple') 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 

/Users/jem/<ipython console> in <module>() 

TypeError: 'fruit' is an invalid keyword argument for this function 
>>> bool('a') 
True 
+0

Tôi không biết, bởi vì nó có ý nghĩa. Tôi đã bỏ phiếu cho bạn :) – TIMEX

+4

(Tôi đã không downvote, nhưng) Việc thiếu một sự trở lại boolean không phải là _cause_ của không có khả năng sử dụng nó trong một câu lệnh 'if()'. Cả hai giới hạn này là _side-effects_ của ngôn ngữ xác định nhiệm vụ như một câu lệnh chứ không phải là một biểu thức. –

2

Nếu bạn muốn viết mã bằng PHP (hoặc C), hãy viết mã trong đó. Đừng cố ép buộc các phương thức của nó lên một ngôn ngữ khác.

Một trong những nguyên lý cơ bản đằng sau Python (theo ý kiến ​​của tôi) là khả năng đọc của nó. Bạn nên sử dụng:

fruit = isBig(y) 
if fruit: return fruit 

Tôi cũng nên đề cập rằng việc bạn sử dụng isXXX() rất lạ; nó thường được sử dụng để trả về các giá trị boolean. Đặc biệt trong trường hợp này, khi bạn sử dụng nó trong câu lệnh IF.

+2

Tôi không xem xét một trong hai phiên bản nhiều hơn hoặc ít có thể đọc được, nhưng có lẽ đó là từ kinh nghiệm. Ngoài ra, IMHO càng có nhiều _consistent_ để làm cho nó thành một biểu thức, vì '=' trông giống như (và được phân tích cú pháp, cả bởi người phiên dịch và con người), chứ không phải là hàm (câu lệnh ngầm, mặc dù đây không phải là ' t về mặt kỹ thuật đúng). –

+0

Thành thật mà nói, bạn không thể luôn sử dụng ngôn ngữ bạn muốn cho một dự án, làm cho một trong những câu trả lời hữu ích nhất mà tôi từng thấy. Nếu tôi có thể bầu bạn xuống một chục lần, tôi sẽ. – Rabbit

+1

Thỏ, nếu bạn được yêu cầu sử dụng một ngôn ngữ cụ thể vì bất kỳ lý do gì, bạn nên sử dụng nó đúng cách. Cố gắng để shoehorn cấu trúc ngôn ngữ khác là một ý tưởng ngu ngốc. Tôi đã nhìn thấy những điều kỳ lạ như '#define bắt đầu {' trong mã C vì các lập trình viên Pascal không muốn thích nghi. Đó là loại hành vi làm cho mã vô ích trong _both_ ngôn ngữ. – paxdiablo

8

Lớp lót một không hoạt động bởi vì, trong Python, gán (fruit = isBig(y)) là một câu lệnh, không phải là một biểu thức. Trong C, C++, Perl, và vô số các ngôn ngữ khác, nó là một biểu thức, và bạn có thể đặt nó trong một số if hoặc while hoặc bất cứ thứ gì bạn thích, nhưng không phải bằng Python, bởi vì những người sáng tạo Python nghĩ rằng điều này quá dễ bị lạm dụng (hoặc lạm dụng) để viết mã "thông minh" (như bạn đang cố gắng).

Ngoài ra, ví dụ của bạn khá ngớ ngẩn. isBig() sẽ luôn luôn đánh giá là true, vì chuỗi duy nhất sai là chuỗi trống (""), do đó, câu lệnh if của bạn là vô ích trong trường hợp này. Tôi cho rằng đó chỉ đơn giản là những gì bạn đang cố gắng làm. Chỉ cần làm điều này:

tmp = isBig(y) 
if tmp: return tmp 

Thực sự còn tồi tệ hơn nhiều không?

+2

Cảm ơn bạn. Nhân tiện, khi bạn có 100 như thế này, điều đó còn tồi tệ hơn nhiều. :) – TIMEX

+5

Khi bạn có 100 dòng như thế này, có vẻ như giải pháp của bạn là tối ưu, nhưng tôi không thể nói mà không biết bạn đang làm. –

+1

Ít nhất, hãy đưa các trường hợp thử nghiệm của bạn vào một danh sách và lặp lại nó để tránh viết chúng ra như thế. –

-3
print "apple" if x > 4 else "orange" 
+0

Điều này không liên quan gì đến câu hỏi. –

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