क्या किसी हालत में असाइनमेंट करना संभव है?
पूर्व के लिए।
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
>>>
तो, नहीं।
x = x + 1अतिरिक्त देखने समय की आवश्यकता है, जबकि x += 1कुछ हद तक तेजी से गया था, लेकिन मुझे यकीन है कि कर रहा हूँ वह भी कर रही पसंद नहीं आया कि ज्यादा। :-)
PEP572 में अजगर 3.8 लाएगा
सार
यह नोटेशन NAME: = expr का उपयोग करके किसी अभिव्यक्ति के भीतर चर को असाइन करने का एक तरीका बनाने के लिए एक प्रस्ताव है। एक नया अपवाद, TargetScopeError जोड़ा गया है, और मूल्यांकन क्रम में एक बदलाव है।
https://lwn.net/Articles/757713/
"PEP 572 मेस" जीवन के लिए परोपकारी तानाशाह (BDFL) गुइडो वैन रोसुम के नेतृत्व में 2018 पायथन लैंग्वेज समिट सत्र का विषय था। PEP 572 भाषा में असाइनमेंट एक्सप्रेशंस (या "इनलाइन असाइनमेंट") जोड़ना चाहता है, लेकिन इसने अजगर-देव मेलिंग सूची पर कई विशाल थ्रेड पर एक लंबी चर्चा को देखा है - अजगर-विचारों के कई दौर के बाद भी। वे धागे अक्सर विवादास्पद थे और स्पष्ट रूप से उस बिंदु पर प्रकाशमान थे जहां कई शायद सिर्फ उन्हें बाहर निकालते थे। शिखर सम्मेलन में, वैन रोसुम ने फीचर प्रस्ताव का अवलोकन किया, जो उन्हें स्वीकार करने की ओर झुकाव है, लेकिन वह यह भी चर्चा करना चाहता था कि भविष्य में इस तरह के थ्रेड विस्फोट से कैसे बचा जाए।
https://www.python.org/dev/peps/pep-0572/#examples-from-the-python-standard-library
पायथन मानक पुस्तकालय से उदाहरण
site.py env_base का उपयोग केवल इन पंक्तियों पर किया जाता है, यदि इसका असाइनमेंट ब्लॉक के "हेडर" के रूप में चलता है।
वर्तमान:
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 anscopy.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.pytz का उपयोग केवल s + = tz के लिए किया जाता है, यदि इसके कार्यक्षेत्र को इसके दायरे को दिखाने में मदद करता है।
वर्तमान:
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 ssysconfig.py कॉलिंग fp.readline (), जबकि कंडीशन और कॉलिंग .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 युक्त स्कोप (यानी परिणाम या सामान के समान स्तर पर) में बद्ध है।
स्थिति मान कैप्चर करना असाइनमेंट अभिव्यक्तियों का उपयोग इफ़र या स्टेटमेंट के हेडर में अच्छे प्रभाव के लिए किया जा सकता है:
# 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)विशेष रूप से लूप के साथ, यह एक अनंत लूप, एक असाइनमेंट और एक शर्त रखने की आवश्यकता को दूर कर सकता है। यह एक लूप के बीच एक चिकनी समानांतर बनाता है जो बस एक फ़ंक्शन कॉल को अपनी स्थिति के रूप में उपयोग करता है, और एक जो अपनी स्थिति के रूप में उपयोग करता है लेकिन वास्तविक मूल्य का भी उपयोग करता है।
कांटा निम्न-स्तरीय UNIX दुनिया से एक उदाहरण है:
if pid := os.fork(): # Parent code else: # Child code
http://docs.python.org/tutorial/datastructures.html
ध्यान दें कि पायथन में, सी के विपरीत, असाइनमेंट अभिव्यक्तियों के अंदर नहीं हो सकता है। सी प्रोग्रामर इस बारे में बड़बड़ा सकते हैं, लेकिन यह सी कार्यक्रमों में सामने आने वाली समस्याओं के एक सामान्य वर्ग से बचता है: टाइपिंग = एक अभिव्यक्ति में == जब इरादा था।
और देखें:
http://effbot.org/pyfaq/why-can-ti-use-an-assignment-in-an-expression.htm
if (foo = 'bar')जबकि मूल्य का परीक्षण करना चाहते हैं foo।
=
नहींं, BDFL उस सुविधा को पसंद नहीं करता था।
जहां से मैं बैठता हूं, गुइडो वैन रोसुम, "बेनेवोलेंट डिक्टेटर फॉर लाइफ", ने अजगर को जितना हो सके उतना आसान रखने के लिए कड़ा संघर्ष किया है। हम उनके द्वारा किए गए कुछ फैसलों से वंचित कर सकते हैं - मैंने पसंद किया होगा 'मैंने कहा' 'अधिक बार। लेकिन यह तथ्य कि पायथन को डिजाइन करने वाली समिति नहीं रही है, लेकिन एक भरोसेमंद "सलाहकार बोर्ड", जो काफी हद तक योग्यता के आधार पर है, एक डिजाइनर की संवेदनाओं को छानकर , एक अच्छी भाषा का एक नरक, IMHO का उत्पादन किया है।
if letजब मेरे पास एक if elif श्रृंखला है, लेकिन प्रत्येक मामले में स्थिति के मूल्य को संग्रहीत और उपयोग करने की आवश्यकता है।
सीधे नहीं, मेरी इस पुरानी रेसिपी के अनुसार - लेकिन जैसा कि रेसिपी कहती है कि शब्दार्थ समतुल्य का निर्माण करना आसान है, उदाहरण के लिए यदि आपको सी-कोडेड रेफरेंस अल्गोरिदम से सीधे ट्रांसलेट करने की आवश्यकता है (अधिक-मुहावरेदार पाइथन को रिफैक्ट करने से पहले); -)। अर्थात:
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, आपके विशिष्ट मामले के लिए एक बहुत ही मुहावरेदार रूप है, यदि आप जानते हैं कि फालिश मूल्य क्या somefuncहो सकता है जब वह एक फालिश मूल्य (जैसे 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
हां, लेकिन केवल पायथन 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
नहीं, पायथन में असाइनमेंट एक कथन है, एक अभिव्यक्ति नहीं है।
पायथन 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
पायथन में 3 ट्रू और गलत कीवर्ड हैं, इसलिए अब कोई जोखिम नहीं है।
== Trueवैसे भी दाईं ओर डालते हैं ।
असाइनमेंट ऑपरेटर - जिसे अनौपचारिक रूप से वालरस ऑपरेटर के रूप में भी जाना जाता है - PEP572 में 28-फरवरी -2018 को बनाया गया था ।
पूर्णता के लिए, मैं संबंधित भागों को पोस्ट करूंगा ताकि आप 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)*