如何避免编写request.GET.get()两次才能打印?
我来自PHP背景,想知道是否有办法在Python中做到这一点。
在PHP中,你可以像这样一石二鸟:
代替:
if(getData()){ $data = getData(); echo $data; }
我可以做这个:
if($data = getData()){ echo $data; }
您检查getData()
存在,如果存在,则将其分配给一个语句中的variables。
我想知道是否有办法在Python中做到这一点? 所以不要这样做:
if request.GET.get('q'): q = request.GET.get('q') print q
避免编写request.GET.get('q')
两次。
可能不完全是你在想什么,但…
q = request.GET.get('q') if q: print q
这个?
看到我8岁的食谱在这里只是这个任务。
# 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())
亚历克斯的答案的变化:
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()
用法:
if save_data(get_input()): print save_data.value
或者如果您更喜欢另一个界面:
if save_data.set(get_input()): print save_data.get()
我会发现这有助于在if-elif-elif-elif等结构中testing一系列正则expression式,就像在这个SO问题中一样 :
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)
q = request.GET.get('q') if q: print q else: # q is None ...
没有办法一次做任务和条件。
如果get()在不存在的时候抛出一个exception,你可以这样做
try: q = request.GET.get('q') print q except : pass
那么,这将是一个方法
q = request.GET.get('q') if q: print q
一个简短的(但不是优越的,由于打印没什么)的方式将是
print request.GET.get('q') or '',
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
一个可能的方法来做到这一点,而不必在之前设置variables,可能是这样的:
if (lambda x: globals().update({'q':x}) or True if x else False)(request.GET.get('q')): print q
..这只是为了好玩 – 这种方法不应该被使用,因为它很丑陋,一见难以理解,它会创build/覆盖一个全局variables(只有当条件满足时,虽然)
只需尝试:
print(request.GET.get('q', ''))
如果第一个参数不存在,基本上不会显示任何内容(请参阅dict.get
)。
另一种解决scheme是在Python中使用条件expression式:
<expression1> if <condition> else <expression2>
但是最终会重复两次variables,例如:
print(request.GET.get('q') if request.GET.get('q') else '')
对于循环中的variables赋值,请在此处检查。