우리가 조건부로 과제를 할 수 있습니까?
조건부로 과제를 하는 것이 가능합니까?
예를 들면.
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 3.8에서 가능합니다.
if a := some_func():
업데이트 - 원본 답변이 맨 아래에 있습니다.
Python 3.8은 PEP572를 도입할 예정입니다.
이것은 다음과 같은 표기법을 사용하여 식 내 변수에 할당하는 방법을 만들기 위한 제안입니다.NAME := expr
예외인 새운예외로,,TargetScopeError
가 추가되고 평가 순서에 한 가지 변경 사항이 있습니다.
https://lwn.net/Articles/757713/
"PEP 572 혼란"은 생명을 위한 자비로운 독재자(BDFL) Guido van Rossum이 이끄는 2018 파이썬 언어 정상회담 세션의 주제였습니다.PEP 572는 언어에 할당 표현식(또는 "인라인 할당")을 추가하려고 하지만 python-dev 메일링 목록에서 python-dev 메일링 목록의 여러 개의 거대한 스레드에 대한 오랜 논의를 거쳤습니다.이러한 스레드는 종종 논쟁적이었고 많은 사람들이 그냥 무시했을 정도로 분명히 볼륨이 있었습니다.Van Rossum은 정상회담에서 특집 제안의 개요를 발표했는데, 그는 이 제안을 받아들이는 경향이 있는 것처럼 보이지만, 향후 이러한 종류의 스레드 폭발을 피할 수 있는 방법에 대해서도 논의하고 싶었습니다.
https://www.python.org/dev/peps/pep-0572/ #일반적인 표준 웹사이트에서 검색
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 코드는 더 규칙적으로 보이고 여러 중첩된 if를 피합니다. (이 예제의 출처는 부록 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을 호출하면 .match를 호출하면 if 행이 코드를 더 압축합니다.
이해하기 어렵게 만드는 것.
현재:
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 루프에서는 무한 루프, 할당 및 조건을 가질 필요가 없습니다.또한 단순히 함수 호출을 조건으로 사용하는 루프와 이를 조건으로 사용하면서도 실제 값을 사용하는 루프 사이에 원활한 병렬을 생성합니다.
포크 낮은 수준의 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-t-i-use-an-assignment-in-an-expression.htm
아니요, BDFL은 그 기능을 좋아하지 않았습니다.
제가 보기에 "평생 은혜로운 독재자"인 Guido van Rossum은 파이썬을 최대한 단순하게 유지하기 위해 열심히 싸웠습니다.우리는 그가 내린 몇 가지 결정에 대해 논쟁할 수 있습니다. 저는 그가 '아니오'라고 더 자주 말했으면 좋았을 것입니다.그러나 파이썬을 설계하는 위원회가 존재하지 않고, 대신에 한 디자이너의 감성을 통해 필터링하는 주로 장점에 기반한 신뢰할 수 있는 "자문 위원회"가 있다는 사실은 IMHO라는 멋진 언어를 만들어냈습니다.
예, 하지만 Python 3.8 이상에서만 사용할 수 있습니다.
PEP 572는 Assignment Expressions를 제안하며 이미 수락되었습니다.
# 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
직접적인 것은 아닙니다. 저의 이 오래된 레시피에 따르면 -- 하지만 레시피에 따르면 의미론적 동등한 것을 구축하는 것이 쉽습니다. 예를 들어 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, 당신의 특정 사례에 대한 매우 관용적인 Pythonic 형식, 만약 당신이 정확히 어떤 거짓된 값을 알고 있다면.somefunc
값 잘된값반반면예수환될있하습니다환을못예▁(()을 반환할 때 될 수 .0
), 는
for a in iter(somefunc, 0):
# use a
따라서 이 특정한 경우에는 리팩터링이 매우 쉬울 것입니다;-).
수익률이 어떠한 종류의 허위가치라도 될 수 있다면 (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에서 할당은 식이 아니라 문입니다.
Python 3.8의 새로운 기능 덕분에 이 버전에서 이러한 작업을 수행할 수 있지만 사용하지는 않습니다.=
하지만 에이다와 같은 할당 연산자.:=
문서의 예:
# Handle a matched regex
if (match := pattern.search(data)) is not None:
# Do something with match
할당을 수행하는 기능을 정의할 수 있습니다.
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)
할당 조건이 불법인 이유 중 하나는 실수를 하고 참 또는 거짓을 할당하는 것이 더 쉽기 때문입니다.
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는 키워드이므로 더 이상 위험이 없습니다.
비공식적으로 바다코끼리 연산자로도 알려진 할당 연산자는 PEP572에서 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)*
언급URL : https://stackoverflow.com/questions/2603956/can-we-have-assignment-in-a-condition
'sourcecode' 카테고리의 다른 글
PHP에서 업로드 형식의 파일 확장자 확인 (0) | 2023.08.31 |
---|---|
jquery 및 ajax를 사용하여 json 개체를 mvc 컨트롤러에 게시합니다. (0) | 2023.08.31 |
도커가 마리아에게 링크를 작성합니다.DB (0) | 2023.08.31 |
파이썬에서 두 배의 정밀 부동값? (0) | 2023.08.26 |
AJAX에서 device의 401 상태를 우아하게 처리하려면 어떻게 해야 합니까? (0) | 2023.08.26 |