2009-11-02 32 views
38

Tôi đến từ một nền tảng PHP và muốn biết nếu có một cách để làm điều này trong Python.Cách tránh viết request.GET.get() hai lần để in?

Trong PHP bạn có thể giết chết 2 con chim với một đá như thế này:

Thay vì:

if(getData()){ 
    $data = getData(); 
    echo $data; 
} 

tôi có thể làm điều này:

if($data = getData()){ 
    echo $data; 
} 

Bạn hãy kiểm tra xem nếu getData() tồn tại VÀ nếu có, bạn gán nó cho một biến trong một câu lệnh.

Tôi muốn biết liệu có cách nào để thực hiện điều này bằng Python không? Vì vậy, thay vì làm điều này:

if request.GET.get('q'): 
    q = request.GET.get('q') 
    print q 

tránh viết request.GET.get('q') hai lần.

+0

Bạn có hướng dẫn bằng Python được đánh dấu trang không? Cái nào? –

+1

Chỉ cần một chính thức: http://docs.python.org/tutorial/ – givp

+2

Rất may, Python không có sự phản ứng C này, và nói chung, trong hầu hết các ngôn ngữ kế thừa từ C/C++, việc sử dụng nó được cau mày khi vì lý do dễ đọc và rõ ràng. –

Trả lời

25

Có lẽ không chính xác những gì bạn đang nghĩ, nhưng ...

q = request.GET.get('q') 
if q: 
    print q 

này?

+0

vâng, đúng vậy. mẫu là sử dụng một biến nếu và chỉ khi nó tồn tại (có nghĩa là nó cho một giá trị hợp lệ, tức là bất cứ điều gì trừ * Sai *). –

+0

Cảm ơn, có vẻ như đây là cách tốt nhất để làm điều đó. Như @Adam nói, không thể thực hiện điều này bằng Python. Cảm ơn. – givp

+7

Hạn chế của giải pháp này là nếu bạn muốn sử dụng nó trong một loạt các if-elif-elif-elif vv Ví dụ, xem câu hỏi SO khác: http://stackoverflow.com/questions/122277/how-do -you-dịch-this-regular-expression-idiom-from-perl-into-python –

24

Xem công thức 8 tuổi của tôi here chỉ cho tác vụ này.

# In Python, you can't code "if x=foo():" -- assignment is a statement, thus 
# you can't fit it into an expression, as needed for conditions of if and 
# while statements, &c. No problem, if you just structure your code around 
# this. But sometimes you're transliterating C, or Perl, or ..., and you'd 
# like your transliteration to be structurally close to the original. 
# 
# No problem, again! One tiny, simple utility class makes it easy...: 

class DataHolder: 
    def __init__(self, value=None): self.value = value 
    def set(self, value): self.value = value; return value 
    def get(self): return self.value 
# optional but handy, if you use this a lot, either or both of: 
setattr(__builtins__,'DataHolder',DataHolder) 
setattr(__builtins__,'data',DataHolder()) 

# and now, assign-and-set to your heart's content: rather than Pythonic 
while 1: 
    line = file.readline() 
    if not line: break 
    process(line) 
# or better in modern Python, but quite far from C-like idioms: 
for line in file.xreadlines(): 
    process(line) 
# you CAN have your C-like code-structure intact in transliteration: 
while data.set(file.readline()): 
    process(data.get()) 
+29

Bạn có một đứa trẻ 8 tuổi khá thông minh! ;) – unutbu

+2

@unutbu, heh - đó sẽ là con mèo (cũ) của tôi khi con tôi lớn hơn một chút ... con gái tôi mới bắt đầu bằng tiến sĩ về kỹ thuật viễn thông (hệ thống radio tiên tiến, chủ yếu) ... ;-) –

0

Vâng, đây sẽ là một trong những cách

q = request.GET.get('q') 
if q: 
    print q 

Một briefer (nhưng không cao, do các cuộc gọi để in từ hư không) cách sẽ là

print request.GET.get('q') or '', 
2
q = request.GET.get('q') 
if q: 
    print q 
else: 
    # q is None 
    ... 

Không có cách nào để thực hiện nhiệm vụ và điều kiện trong một lần ...

+0

Rõ ràng là tốt hơn là ngầm. Số lượng khả năng đọc. Các trường hợp đặc biệt không đủ đặc biệt để phá vỡ các quy tắc. Bạn đang tiết kiệm rất nhiều không gian dọc trong mã của bạn bằng cách không viết tất cả những dòng không có gì ngoài một cú đúp phải, vậy tại sao không đi cho rõ ràng trong Python? Cá nhân tôi cắt hàm răng trên C và đã viết mã Python trong 12 năm nay, và tôi chưa bao giờ nhận ra tính năng này bị thiếu. Bạn không cần phải làm điều này. –

+0

@Michael: Tôi đồng ý trong hầu hết các trường hợp. Tôi chỉ thiếu nó trong trường hợp sử dụng cụ thể của việc kiểm tra nhiều biểu thức chính quy, như được mô tả trong câu hỏi SO khác: http://stackoverflow.com/questions/122277/how-do-you-translate-this-regular-expression- Thành ngữ-từ-perl-into-python –

2

Nếu get() ném một ngoại lệ khi nó không có ở đó, bạn có thể làm

try: 
    q = request.GET.get('q') 
    print q 
except : 
    pass 
9

Một biến thể của Alex's answer:

class DataHolder: 
    def __init__(self, value=None, attr_name='value'): 
     self._attr_name = attr_name 
     self.set(value) 
    def __call__(self, value): 
     return self.set(value) 
    def set(self, value): 
     setattr(self, self._attr_name, value) 
     return value 
    def get(self): 
     return getattr(self, self._attr_name) 
save_data = DataHolder() 

Cách sử dụng:

if save_data(get_input()): 
    print save_data.value 

hoặc nếu bạn thích một giao diện thay thế:

if save_data.set(get_input()): 
    print save_data.get() 

tôi sẽ tìm thấy hữu ích này để kiểm tra một loạt các biểu thức thông thường trong một if-elif-elif-elif vv xây dựng, như trong this SO question:

import re 

input = u'test bar 123' 
save_match = DataHolder(attr_name='match') 
if save_match(re.search('foo (\d+)', input)): 
    print "Foo" 
    print save_match.match.group(1) 
elif save_match(re.search('bar (\d+)', input)): 
    print "Bar" 
    print save_match.match.group(1) 
elif save_match(re.search('baz (\d+)', input)): 
    print "Baz" 
    print save_match.match.group(1) 
+0

Tôi thích việc bạn thêm '__call __()' vào DataHolder, nhưng tôi không hiểu tại sao nó hữu ích để chỉ định 'attr_name'. Nếu DataHolder là một singleton hoặc nếu một thể hiện của nó có thể chứa nhiều giá trị, mỗi giá trị trong các thuộc tính khác nhau, tôi sẽ hiểu, nhưng nó dường như không có mục đích mạnh ở đây. –

+1

@LS: Có, tôi có thể sửa nó thành 'giá trị' hoặc' x'.Nhưng [tên biến tốt] (http://c2.com/cgi/wiki?GoodVariableNames) cải thiện khả năng đọc. Đó là bản chất của nó. –

0
config_hash = {} 
tmp_dir = ([config_hash[x] for x in ["tmp_dir"] if config_hash.has_key(x)] or ["tmp"])[0] 
print tmp_dir 
config_hash["tmp_dir"] = "cat" 
tmp_dir = ([config_hash[x] for x in ["tmp_dir"] if config_hash.has_key(x)] or ["tmp"])[0] 
print tmp_dir 
0

một cách tốt để làm điều đó, mà không cần thiết phải đặt biến trước, có thể là:

if (lambda x: globals().update({'q':x}) or True if x else False)(request.GET.get('q')): 
    print q 

..Nó chỉ để cho vui - phương pháp này không nên được sử dụng, bởi vì nó là hack xấu xí, khó hiểu ngay từ cái nhìn đầu tiên, và nó tạo/ghi đè lên một biến toàn cục (chỉ khi điều kiện được đáp ứng)

0

Chỉ cần thử:

print(request.GET.get('q', '')) 

về cơ bản sẽ không in được gì nếu đối số đầu tiên không có mặt (xem dict.get).


giải pháp thay thế sẽ được sử dụng một biểu thức điều kiện bằng Python:

<expression1> if <condition> else <expression2> 

nhưng bạn sẽ kết thúc lặp lại biến hai lần, ví dụ:

print(request.GET.get('q') if request.GET.get('q') else '') 

Đối các bài tập thay đổi trong các vòng lặp, kiểm tra trong here.

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