Python 我们能在条件允许的情况下完成任务吗?
有可能在某种条件下进行赋值吗 例如Python 我们能在条件允许的情况下完成任务吗?,python,Python,有可能在某种条件下进行赋值吗 例如 if (a=some_func()): # Use a 为什么不试试呢 >>> def some_func(): ... return 2 ... >>> if (a = some_func()): File "<stdin>", line 1 if (a = some_func()): ^ SyntaxError: invalid syntax
if (a=some_func()):
# Use a
为什么不试试呢
>>> def some_func():
... return 2
...
>>> if (a = some_func()):
File "<stdin>", line 1
if (a = some_func()):
^
SyntaxError: invalid syntax
否。Python中的赋值是语句,而不是表达式。UPDATE-原始答案在底部附近 Python3.8将引入 摘要
这是一个关于创建一种分配给变量的方法的建议 在表达式中使用符号
NAME:=expr
。一个新的例外,
添加了TargetScopeError
,并对评估进行了一次更改
秩序
“PEP572混乱”是2018年Python语言峰会的主题
由仁慈的终身独裁者(BDFL)Guido van Rossum领导的会议。
PEP 572试图添加赋值表达式(或“内联赋值”)
对语言,但它已经看到了一个长期的讨论,在多个方面
python-dev邮件列表上的大量线程,即使在多次发送之后也是如此
关于python思想。这些线索往往是有争议的,而且很明显
数量庞大,很多人可能只是对其进行了调整。在
在峰会上,Van Rossum概述了专题提案,其中
他似乎倾向于接受,但他也想讨论如何接受
以避免将来出现这种线程爆炸
Python标准库中的示例
site.py env_base仅用于这些行,将其指定放在if上,并将其作为块的“标题”移动。
当前:
env_base = os.environ.get("PYTHONUSERBASE", None)
if env_base:
return env_base
if self._is_special:
ans = self._check_nans(context=context)
if ans:
return ans
reductor = dispatch_table.get(cls)
if reductor:
rv = reductor(x)
else:
reductor = getattr(x, "__reduce_ex__", None)
if reductor:
rv = reductor(4)
else:
reductor = getattr(x, "__reduce__", None)
if reductor:
rv = reductor()
else:
raise Error(
"un(deep)copyable object of type %s" % cls)
s = _format_time(self._hour, self._minute,
self._second, self._microsecond,
timespec)
tz = self._tzstr()
if tz:
s += tz
return s
while True:
line = fp.readline()
if not line:
break
m = define_rx.match(line)
if m:
n, v = m.group(1, 2)
try:
v = int(v)
except ValueError:
pass
vars[n] = v
else:
m = undef_rx.match(line)
if m:
vars[m.group(1)] = 0
改进:
if env_base := os.environ.get("PYTHONUSERBASE", None):
return env_base
_pydecimal.py
if self._is_special and (ans := self._check_nans(context=context)):
return ans
if reductor := dispatch_table.get(cls):
rv = reductor(x)
elif reductor := getattr(x, "__reduce_ex__", None):
rv = reductor(4)
elif reductor := getattr(x, "__reduce__", None):
rv = reductor()
else:
raise Error("un(deep)copyable object of type %s" % cls)
datetime.py
s = _format_time(self._hour, self._minute,
self._second, self._microsecond,
timespec)
if tz := self._tzstr():
s += tz
return s
while line := fp.readline():
if m := define_rx.match(line):
n, v = m.group(1, 2)
try:
v = int(v)
except ValueError:
pass
vars[n] = v
elif m := undef_rx.match(line):
vars[m.group(1)] = 0
避免嵌套if并删除一个缩进级别
当前:
env_base = os.environ.get("PYTHONUSERBASE", None)
if env_base:
return env_base
if self._is_special:
ans = self._check_nans(context=context)
if ans:
return ans
reductor = dispatch_table.get(cls)
if reductor:
rv = reductor(x)
else:
reductor = getattr(x, "__reduce_ex__", None)
if reductor:
rv = reductor(4)
else:
reductor = getattr(x, "__reduce__", None)
if reductor:
rv = reductor()
else:
raise Error(
"un(deep)copyable object of type %s" % cls)
s = _format_time(self._hour, self._minute,
self._second, self._microsecond,
timespec)
tz = self._tzstr()
if tz:
s += tz
return s
while True:
line = fp.readline()
if not line:
break
m = define_rx.match(line)
if m:
n, v = m.group(1, 2)
try:
v = int(v)
except ValueError:
pass
vars[n] = v
else:
m = undef_rx.match(line)
if m:
vars[m.group(1)] = 0
改进:
if env_base := os.environ.get("PYTHONUSERBASE", None):
return env_base
_pydecimal.py
if self._is_special and (ans := self._check_nans(context=context)):
return ans
if reductor := dispatch_table.get(cls):
rv = reductor(x)
elif reductor := getattr(x, "__reduce_ex__", None):
rv = reductor(4)
elif reductor := getattr(x, "__reduce__", None):
rv = reductor()
else:
raise Error("un(deep)copyable object of type %s" % cls)
datetime.py
s = _format_time(self._hour, self._minute,
self._second, self._microsecond,
timespec)
if tz := self._tzstr():
s += tz
return s
while line := fp.readline():
if m := define_rx.match(line):
n, v = m.group(1, 2)
try:
v = int(v)
except ValueError:
pass
vars[n] = v
elif m := undef_rx.match(line):
vars[m.group(1)] = 0
copy.py代码看起来更规则,如果需要,可以避免多重嵌套。(本例来源见附录A。)
当前:
env_base = os.environ.get("PYTHONUSERBASE", None)
if env_base:
return env_base
if self._is_special:
ans = self._check_nans(context=context)
if ans:
return ans
reductor = dispatch_table.get(cls)
if reductor:
rv = reductor(x)
else:
reductor = getattr(x, "__reduce_ex__", None)
if reductor:
rv = reductor(4)
else:
reductor = getattr(x, "__reduce__", None)
if reductor:
rv = reductor()
else:
raise Error(
"un(deep)copyable object of type %s" % cls)
s = _format_time(self._hour, self._minute,
self._second, self._microsecond,
timespec)
tz = self._tzstr()
if tz:
s += tz
return s
while True:
line = fp.readline()
if not line:
break
m = define_rx.match(line)
if m:
n, v = m.group(1, 2)
try:
v = int(v)
except ValueError:
pass
vars[n] = v
else:
m = undef_rx.match(line)
if m:
vars[m.group(1)] = 0
改进:
if env_base := os.environ.get("PYTHONUSERBASE", None):
return env_base
_pydecimal.py
if self._is_special and (ans := self._check_nans(context=context)):
return ans
if reductor := dispatch_table.get(cls):
rv = reductor(x)
elif reductor := getattr(x, "__reduce_ex__", None):
rv = reductor(4)
elif reductor := getattr(x, "__reduce__", None):
rv = reductor()
else:
raise Error("un(deep)copyable object of type %s" % cls)
datetime.py
s = _format_time(self._hour, self._minute,
self._second, self._microsecond,
timespec)
if tz := self._tzstr():
s += tz
return s
while line := fp.readline():
if m := define_rx.match(line):
n, v = m.group(1, 2)
try:
v = int(v)
except ValueError:
pass
vars[n] = v
elif m := undef_rx.match(line):
vars[m.group(1)] = 0
tz仅用于s+=tz,将其赋值移动到if帮助中
显示其范围
当前:
env_base = os.environ.get("PYTHONUSERBASE", None)
if env_base:
return env_base
if self._is_special:
ans = self._check_nans(context=context)
if ans:
return ans
reductor = dispatch_table.get(cls)
if reductor:
rv = reductor(x)
else:
reductor = getattr(x, "__reduce_ex__", None)
if reductor:
rv = reductor(4)
else:
reductor = getattr(x, "__reduce__", None)
if reductor:
rv = reductor()
else:
raise Error(
"un(deep)copyable object of type %s" % cls)
s = _format_time(self._hour, self._minute,
self._second, self._microsecond,
timespec)
tz = self._tzstr()
if tz:
s += tz
return s
while True:
line = fp.readline()
if not line:
break
m = define_rx.match(line)
if m:
n, v = m.group(1, 2)
try:
v = int(v)
except ValueError:
pass
vars[n] = v
else:
m = undef_rx.match(line)
if m:
vars[m.group(1)] = 0
改进:
if env_base := os.environ.get("PYTHONUSERBASE", None):
return env_base
_pydecimal.py
if self._is_special and (ans := self._check_nans(context=context)):
return ans
if reductor := dispatch_table.get(cls):
rv = reductor(x)
elif reductor := getattr(x, "__reduce_ex__", None):
rv = reductor(4)
elif reductor := getattr(x, "__reduce__", None):
rv = reductor()
else:
raise Error("un(deep)copyable object of type %s" % cls)
datetime.py
s = _format_time(self._hour, self._minute,
self._second, self._microsecond,
timespec)
if tz := self._tzstr():
s += tz
return s
while line := fp.readline():
if m := define_rx.match(line):
n, v = m.group(1, 2)
try:
v = int(v)
except ValueError:
pass
vars[n] = v
elif m := undef_rx.match(line):
vars[m.group(1)] = 0
sysconfig.py在while条件中调用fp.readline(),并在if行中调用.match(),使代码更加紧凑,而无需
使它更难理解
当前:
env_base = os.environ.get("PYTHONUSERBASE", None)
if env_base:
return env_base
if self._is_special:
ans = self._check_nans(context=context)
if ans:
return ans
reductor = dispatch_table.get(cls)
if reductor:
rv = reductor(x)
else:
reductor = getattr(x, "__reduce_ex__", None)
if reductor:
rv = reductor(4)
else:
reductor = getattr(x, "__reduce__", None)
if reductor:
rv = reductor()
else:
raise Error(
"un(deep)copyable object of type %s" % cls)
s = _format_time(self._hour, self._minute,
self._second, self._microsecond,
timespec)
tz = self._tzstr()
if tz:
s += tz
return s
while True:
line = fp.readline()
if not line:
break
m = define_rx.match(line)
if m:
n, v = m.group(1, 2)
try:
v = int(v)
except ValueError:
pass
vars[n] = v
else:
m = undef_rx.match(line)
if m:
vars[m.group(1)] = 0
改进:
if env_base := os.environ.get("PYTHONUSERBASE", None):
return env_base
_pydecimal.py
if self._is_special and (ans := self._check_nans(context=context)):
return ans
if reductor := dispatch_table.get(cls):
rv = reductor(x)
elif reductor := getattr(x, "__reduce_ex__", None):
rv = reductor(4)
elif reductor := getattr(x, "__reduce__", None):
rv = reductor()
else:
raise Error("un(deep)copyable object of type %s" % cls)
datetime.py
s = _format_time(self._hour, self._minute,
self._second, self._microsecond,
timespec)
if tz := self._tzstr():
s += tz
return s
while line := fp.readline():
if m := define_rx.match(line):
n, v = m.group(1, 2)
try:
v = int(v)
except ValueError:
pass
vars[n] = v
elif m := undef_rx.match(line):
vars[m.group(1)] = 0
简化列表理解通过捕获条件,列表理解可以有效地映射和过滤:
类似地,子表达式可以在主表达式中重用,
第一次使用时给它起一个名字:
stuff = [[y := f(x), x/y] for x in range(5)]
请注意,在这两种情况下,变量y都绑定在包含
范围(即与结果或内容处于同一级别)
捕获条件值赋值表达式可以在if或while语句的标头中发挥良好效果:
特别是对于while循环,这可以消除对
无限循环、赋值和条件。它还创建了一个
循环之间的平滑并行,该循环仅使用函数调用作为
它的条件,一个使用它作为条件,但也使用
实际值
从低级UNIX世界中选出一个例子:
原始答案
请注意,在Python中,与C不同,
分配不能发生在内部
表达。C程序员可能会抱怨
关于这一点,但它避免了一个常见的问题
C语言中遇到的一类问题
程序:在表达式中键入=
当==是预定的
另见:
不,BDFL不喜欢这个功能 在我坐的地方,Guido van Rossum,“一生仁慈的独裁者”,一直在努力让Python尽可能简单。我们可以质疑他所做的一些决定——我更希望他更经常地说“不”。但事实上,没有一个设计Python的委员会,而是一个值得信赖的“咨询委员会”“主要基于优点,通过过滤一位设计师的敏感度,产生了一种非常好的语言,IMHO。不是直接的,per——但正如食谱所说,很容易建立语义等价物,例如,如果你需要直接从C编码的参考算法进行音译(当然,在重构到更惯用的Python之前;-)。即: 顺便说一句,如果您确切知道falsish值
somefunc
在返回falsish值(例如0
)时可能返回的值,那么这是一种非常惯用的python形式
因此,在这种特定情况下,重构将非常容易;-)
如果返回值可以是任何类型的falsish值(0,None
,'
,…),一种可能性是:
import itertools
for a in itertools.takewhile(lambda x: x, iter(somefunc, object())):
# use a
但您可能更喜欢简单的自定义生成器:
def getwhile(func, *a, **k):
while True:
x = func(*a, **k)
if not x: break
yield x
for a in getwhile(somefunc):
# use a
条件下的赋值是非法的原因之一是容易出错并赋值为真或假:
some_variable = 5
# This does not work
# if True = some_variable:
# do_something()
# This only works in Python 2.x
True = some_variable
print True # returns 5
在Python 3中,True和False是关键字,因此不再存在任何风险。您可以定义一个函数来为自己赋值:
def assign(name, value):
import inspect
frame = inspect.currentframe()
try:
locals_ = frame.f_back.f_locals
finally:
del frame
locals_[name] = value
return value
if assign('test', 0):
print("first", test)
elif assign('xyz', 123):
print("second", xyz)
多亏了它,在这个版本中可以做这样的事情,虽然不使用=
,但使用类似Ada的赋值操作符:=
。文档中的示例:
# Handle a matched regex
if (match := pattern.search(data)) is not None:
# Do something with match
是的,但仅限于Python3.8及以后版本 建议赋值表达式,并已被接受 引用政治公众人物部分:
# Handle a matched regex
if (match := pattern.search(data)) is not None:
# Do something with match
# A loop that can't be trivially rewritten using 2-arg iter()
while chunk := file.read(8192):
process(chunk)
# Reuse a value that's expensive to compute
[y := f(x), y**2, y**3]
# Share a subexpression between a comprehension filter clause and its output
filtered_data = [y for x in data if (y := f(x)) is not None]
在您的具体情况下,您将能够编写
if a := some_func():
# Use a
分配操作员(也称为海象操作员)于2018年2月28日成立 为了完整起见,我将发布相关部分,以便您可以比较3.7和3.8之间的差异:
3.7
---
if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
test: or_test ['if' or_test 'else' test] | lambdef
test_nocond: or_test | lambdef_nocond
lambdef: 'lambda' [varargslist] ':' test
lambdef_nocond: 'lambda' [varargslist] ':' test_nocond
or_test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*
3.8
---
if_stmt: 'if' namedexpr_test ':' suite ('elif' namedexpr_test ':' suite)* ['else' ':' suite]
namedexpr_test: test [':=' test] <---- WALRUS OPERATOR!!!
test: or_test ['if' or_test 'else' test] | lambdef
or_test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*
3.7
---
if stmt:'if'test':'suite('elif'test':'suite)*['else':'suite]
套件:简单|换行缩进stmt+DEDENT
测试:或|测试['if'或|测试'else'测试]| lambdef
测试无约束:或测试无约束
lambdef:'lambda'[varargslist]':'test
lambdef_nocond:'lambda'[varargslist]':'test_nocond
or_测试:and_测试('or'and_测试)*
and_测试:not_测试(‘and’not_测试)*
非|测试:非|非|测试|比较
比较:expr(comp_op expr)*
3.8
---
if_stmt:'if'namedexpr_test':'suite('elif'namedexpr_test':'suite)*['else':'suite]
namedexpr_test:test[':=“test]和Guido不会有任何其他方法。@markransem所有人都向Guido欢呼。正确的。。唉。@javadba这家伙说得对的次数比以前多得多