조건에 할당 할 수 있습니까?
예를 들어.
if (a=some_func()):
# Use a
답변
시도해 보지 않겠습니까?
>>> def some_func():
... return 2
...
>>> a = 2
>>> if (a = some_func()):
File "<stdin>", line 1
if (a = some_func()):
^
SyntaxError: invalid syntax
>>>
그래서 아니야.
업데이트 : 이것은 Python 3.8에서 가능합니다 (다른 구문으로).
답변
업데이트-원래 답변이 하단 근처에 있습니다.
Python 3.8은 PEP572 를 가져올 것입니다 .
Abstract
이것은 NAME : = expr 표기법을 사용하여 표현식 내의 변수에 할당하는 방법을 생성하기위한 제안입니다. 새 예외 인 TargetScopeError가 추가되고 평가 순서에 한 가지 변경 사항이 있습니다.
https://lwn.net/Articles/757713/
“PEP 572 혼란”은 자비로운 독재자 (BDFL) Guido van Rossum이 이끄는 2018 Python Language Summit 세션의 주제였습니다. PEP 572는 언어에 할당 표현식 (또는 “인라인 할당”)을 추가하려고하지만, python-ideas에 대해 여러 차례 반복 한 후에도 python-dev 메일 링 목록에있는 여러 개의 거대한 스레드에 대한 오랜 논의를 보았습니다. 이러한 스레드는 종종 논쟁의 여지가 많았으며 많은 사람들이 아마 방금 조정했을 정도로 방대했습니다. 정상 회담에서 Van Rossum은 기능 제안에 대한 개요를 제공했으며이를 수용하는 경향이 있지만 향후 이러한 종류의 스레드 폭발을 방지하는 방법에 대해서도 논의하고 싶었습니다.
https://www.python.org/dev/peps/pep-0572/#examples-from-the-python-standard-library
Python 표준 라이브러리의 예
site.py env_base는이 행에서만 사용되며 if에 할당을 지정하여 블록의 “헤더”로 이동합니다.
흐름:
env_base = os.environ.get("PYTHONUSERBASE", None) if env_base: return env_base
향상:
if env_base := os.environ.get("PYTHONUSERBASE", None): return env_base _pydecimal.py
중첩 된 경우를 피하고 하나의 들여 쓰기 수준을 제거합니다.
흐름:
if self._is_special: ans = self._check_nans(context=context) if ans: return ans
향상:
if self._is_special and (ans := self._check_nans(context=context)): return ans
copy.py 코드는 더 규칙적으로 보이고 다중 중첩 된 경우를 피합니다. (이 예의 출처는 부록 A를 참조하십시오.)
흐름:
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)
향상:
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
tz는 s + = tz에만 사용되며 if 내에서 할당을 이동하면 범위를 표시하는 데 도움이됩니다.
흐름:
s = _format_time(self._hour, self._minute, self._second, self._microsecond, timespec) tz = self._tzstr() if tz: s += tz return s
향상:
s = _format_time(self._hour, self._minute, self._second, self._microsecond, timespec) if tz := self._tzstr(): s += tz return s
sysconfig.py while 조건에서 fp.readline ()을 호출하고 if 라인에서 .match ()를 호출하면 코드가
이해하기 어렵게 만듭니다.
흐름:
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
향상:
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
목록 이해 단순화 목록 이해는 조건을 캡처하여 효율적으로 매핑하고 필터링 할 수 있습니다.
results = [(x, y, x/y) for x in input_data if (y := f(x)) > 0]
마찬가지로 하위 표현식은 처음 사용할 때 이름을 지정하여 기본 표현식 내에서 재사용 할 수 있습니다.
stuff = [[y := f(x), x/y] for x in range(5)]
두 경우 모두 변수 y는 포함 범위 (즉, 결과 또는 물건과 동일한 수준)에 바인딩됩니다.
조건 값 캡처 할당 표현식은 if 또는 while 문의 헤더에서 좋은 효과를내는 데 사용할 수 있습니다.
# Loop-and-a-half while (command := input("> ")) != "quit": print("You entered:", command) # Capturing regular expression match objects # See, for instance, Lib/pydoc.py, which uses a multiline spelling # of this effect if match := re.search(pat, text): print("Found:", match.group(0)) # The same syntax chains nicely into 'elif' statements, unlike the # equivalent using assignment statements. elif match := re.search(otherpat, text): print("Alternate found:", match.group(0)) elif match := re.search(third, text): print("Fallback found:", match.group(0)) # Reading socket data until an empty string is returned while data := sock.recv(8192): print("Received data:", data)
특히 while 루프를 사용하면 무한 루프, 할당 및 조건이 필요하지 않습니다. 또한 단순히 함수 호출을 조건으로 사용하는 루프와이를 조건으로 사용하지만 실제 값을 사용하는 루프 사이에 매끄러운 병렬을 생성합니다.
Fork 저수준 UNIX 세계의 예 :
if pid := os.fork(): # Parent code else: # Child code
원래 답변
http://docs.python.org/tutorial/datastructures.html
Python에서는 C와 달리 표현식 내에서 할당이 발생할 수 없습니다. C 프로그래머는 이것에 대해 불평 할 수 있지만 C 프로그램에서 발생하는 일반적인 문제를 피할 수 있습니다. ==가 의도되었을 때 표현식에 =를 입력합니다.
참조 :
http://effbot.org/pyfaq/why-can-ti-use-an-assignment-in-an-expression.htm
답변
아니요, BDFL은 그 기능을 좋아하지 않았습니다.
내가 앉은 자리에서 “Benevolent Dictator For Life”인 Guido van Rossum은 Python을 가능한 한 단순하게 유지하기 위해 열심히 싸웠습니다. 우리는 그가 내린 결정 중 일부에 대해 고민 할 수 있습니다. 하지만 파이썬을 설계하는위원회가 없었고, 대신 한 디자이너의 감성을 통해 필터링하는 장점에 기반을 둔 신뢰할 수있는 “자문위원회” 가 하나의 멋진 언어 인 IMHO를 만들어 냈습니다.
답변
아니 직접, 당 내이 오래된 조리법 -하지만 조리법은 당신이 더-관용적 파이썬에 리팩토링하기 전에 (A C 코드 참조 알고리즘에서 직접 음역해야하는 경우, 예를 의미 상당을 구축하기 쉽게 말하는 것처럼, 물론, -). 즉 :
class DataHolder(object):
def __init__(self, value=None): self.value = value
def set(self, value): self.value = value; return value
def get(self): return self.value
data = DataHolder()
while data.set(somefunc()):
a = data.get()
# use a
정확히 알고있는 경우 BTW, 특정 사건에 대한 매우 관용적 파이썬 형태는 falsish 값은 어떻게 somefunc
그것이 falsish 값을 반환 않는 경우 (예를 들어, 반환 할 수 0
있다)
for a in iter(somefunc, 0):
# use a
따라서이 특정 경우에는 리팩토링이 매우 쉬울 것입니다 .-).
반환 될 수 있다면 어떤 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
답변
예,하지만 Python 3.8 이상에서만 가능합니다.
PEP 572 는 할당 표현식을 제안 하고 이미 승인되었습니다.
PEP 의 구문 및 의미론 부분 인용 :
# 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
답변
아니요. Python에서 할당은 표현식이 아니라 명령문입니다.
답변
Python 3.8의 새로운 기능 덕분에 =
Ada와 유사한 할당 연산자를 사용 하지는 않지만이 버전에서 이러한 작업을 수행 할 수 있습니다 :=
. 문서의 예 :
# Handle a matched regex
if (match := pattern.search(data)) is not None:
# Do something with match
