(1) বনাম যখন (সত্য) - কেন পার্থক্য আছে (পাইথন 2 বাইটোকোডে)?


115

পার্লে অসীম লুপগুলি সম্পর্কে এই প্রশ্নের দ্বারা উত্সাহিত: যখন (1) বনাম। (;;) জন্য একটি গতি পার্থক্য আছে? , আমি অজগর একই অনুরূপ চালানোর সিদ্ধান্ত নিয়েছে। আমি প্রত্যাশা করেছিলাম যে সংকলকটি একই বাইট কোডটি উত্পন্ন করবে while(True): passএবং while(1): passএটি আসলে পাইথন ২.। তে এটি নয়।

নিম্নলিখিত লিপি:

import dis

def while_one():
    while 1:
        pass

def while_true():
    while True:
        pass

print("while 1")
print("----------------------------")
dis.dis(while_one)

print("while True")
print("----------------------------")
dis.dis(while_true)

নিম্নলিখিত ফলাফল উত্পাদন করে:

while 1
----------------------------
  4           0 SETUP_LOOP               3 (to 6)

  5     >>    3 JUMP_ABSOLUTE            3
        >>    6 LOAD_CONST               0 (None)
              9 RETURN_VALUE        
while True
----------------------------
  8           0 SETUP_LOOP              12 (to 15)
        >>    3 LOAD_GLOBAL              0 (True)
              6 JUMP_IF_FALSE            4 (to 13)
              9 POP_TOP             

  9          10 JUMP_ABSOLUTE            3
        >>   13 POP_TOP             
             14 POP_BLOCK           
        >>   15 LOAD_CONST               0 (None)
             18 RETURN_VALUE        

ব্যবহার while Trueকরা লক্ষণীয়ভাবে জটিল। কেন?

অন্যান্য প্রসঙ্গে, পাইথনটি Trueসমান 1:

>>> True == 1
True

>>> True + True
2

whileদু'জনকে আলাদা করে কেন ?

আমি লক্ষ্য করেছি যে পাইথন 3 অভিন্ন ক্রিয়াকলাপগুলি ব্যবহার করে বিবৃতিগুলি মূল্যায়ন করে:

while 1
----------------------------
  4           0 SETUP_LOOP               3 (to 6) 

  5     >>    3 JUMP_ABSOLUTE            3 
        >>    6 LOAD_CONST               0 (None) 
              9 RETURN_VALUE         
while True
----------------------------
  8           0 SETUP_LOOP               3 (to 6) 

  9     >>    3 JUMP_ABSOLUTE            3 
        >>    6 LOAD_CONST               0 (None) 
              9 RETURN_VALUE         

বুলিয়ানদের মূল্যায়ন করার পথে পাইথন 3-তে কি কোনও পরিবর্তন আছে?


উত্তর:


124

পাইথন ২.x-এ Trueকোনও কীওয়ার্ড নয়, কেবল একটি বিল্ট-ইন গ্লোবাল ধ্রুবক যা এই boolধরণের 1 তে সংজ্ঞায়িত । সুতরাং দোভাষীকে এখনও সামগ্রীর লোড করতে হবে True। অন্য কথায়, Trueপুনরায় স্বাক্ষরযোগ্য:

Python 2.7 (r27:82508, Jul  3 2010, 21:12:11) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> True = 4
>>> True
4

পাইথন ৩.x এ এটি সত্যিই একটি কীওয়ার্ড এবং সত্যিকারের ধ্রুবক হয়ে যায় :

Python 3.1.2 (r312:79147, Jul 19 2010, 21:03:37) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> True = 4
  File "<stdin>", line 1
SyntaxError: assignment to keyword

এইভাবে দোভাষী তার while True:সাথে লুপটি অসীম লুপের সাথে প্রতিস্থাপন করতে পারেন ।


1
@ এমএইচ: এএফাইক, কী-ওয়ার্ডটি ভাষায় প্রবেশ করা সমীচীন ছিল।
এস .লট


এর মানে কি এই while 1এবং while Trueপাইথন 3 অভিন্ন?
স্টিভোসিয়াক

@ স্টিভেনএম.ভ্যাসেলোরো হ্যাঁ।
কেনেটিএম

14

এটা একদম ঠিক নেই,

এইভাবে দোভাষী দের সময়টিকে প্রতিস্থাপন করতে পারেন: অসীম লুপের সাহায্যে লুপ।

যেহেতু কেউ এখনও লুপ থেকে বেরিয়ে যেতে পারে। তবে এটি সত্য যে এই ধরণের লুপের elseধারাটি পাইথন 3-এ কখনও অ্যাক্সেস করা যাবে না And এবং এটি সত্য যে মান সন্ধানের বিষয়টি সরল করে তোলার জন্য while 1পাইথন 2 এর মতো দ্রুত চালানো হয় ।

পারফরম্যান্স তুলনা

লুপের সময় কিছুটা অযৌক্তিকর জন্য সময়ের মধ্যে পার্থক্যটি দেখানো:

সেটআপ

def while1():
    x = 0
    while 1:
        x += 1
        if x == 10:
            break

def whileTrue():
    x = 0
    while True:
        x += 1
        if x == 10:
            break

পাইথন 2

>>> import timeit
>>> min(timeit.repeat(while1))
0.49712109565734863
>>> min(timeit.repeat(whileTrue))
0.756627082824707

পাইথন ঘ

>>> import timeit
>>> min(timeit.repeat(while1))
0.6462970309949014
>>> min(timeit.repeat(whileTrue))
0.6450748789939098

ব্যাখ্যা

পার্থক্যটি ব্যাখ্যা করতে পাইথন ২ তে:

>>> import keyword
>>> 'True' in keyword.kwlist
False

কিন্তু পাইথন 3 এ:

>>> import keyword
>>> 'True' in keyword.kwlist
True
>>> True = 'true?'
  File "<stdin>", line 1
SyntaxError: can't assign to keyword

যেহেতু Trueপাইথন 3-এ একটি কীওয়ার্ড, তাই অনুবাদককে কেউ অন্য কোনও মান দিয়ে এটি প্রতিস্থাপন করেছে কিনা তা দেখার জন্য মূল্য সন্ধান করতে হবে না। যেহেতু একজন Trueঅন্য মানকে নির্ধারণ করতে পারে, তাই দোভাষীকে প্রতিবার এটি সন্ধান করতে হবে।

পাইথন 2 উপসংহার

পাইথন 2 এ আপনার যদি টাইট, দীর্ঘ-চলমান লুপ থাকে তবে আপনার while 1:পরিবর্তে সম্ভবত ব্যবহার করা উচিত while True:

পাইথন 3 উপসংহার

while True:আপনার লুপটি ভেঙে ফেলার কোনও শর্ত না থাকলে ব্যবহার করুন ।


3

এটি একটি 7-বছরের পুরানো প্রশ্ন যা ইতিমধ্যে একটি দুর্দান্ত উত্তর রয়েছে, তবে প্রশ্নের মধ্যে একটি ভুল ধারণা যা উত্তরগুলির কোনওটিতেই সম্বোধন করা হয়নি, এটি নকল হিসাবে চিহ্নিত অন্যান্য কয়েকটি প্রশ্নের জন্য সম্ভবত বিভ্রান্তিকর করে তোলে।

অন্যান্য প্রসঙ্গে, পাইথনটি সত্য হিসাবে সমান 1:

>>> True == 1
True

>>> True + True
2

কেন দুটি পার্থক্য করে?

আসলে, whileএখানে মোটেও আলাদা কিছু করছে না। এটি পৃথক করে 1এবং Trueঠিক একইভাবে +উদাহরণটি দেয়।


এখানে 2.7:

>>> dis.dis('True == 1')
  1           0 LOAD_GLOBAL              0 (True)
              3 LOAD_CONST               1 (1)
              6 COMPARE_OP               2 (==)
              9 RETURN_VALUE

>>> dis.dis('True == 1')
  1           0 LOAD_GLOBAL              0 (True)
              3 LOAD_GLOBAL              0 (True)
              6 BINARY_ADD
              9 RETURN_VALUE

এখন তুলনা করুন:

>>> dis.dis('1 + 1')
  1           0 LOAD_CONST               1 (2)
              3 RETURN_VALUE

এটি LOAD_GLOBAL (True)প্রত্যেকের জন্য একটি নির্গমন করছে Trueএবং গ্লোবালটির সাথে অপ্টিমাইজার কিছুই করতে পারে না। সুতরাং, whileপৃথক করে 1এবং Trueঠিক একই কারণে যা +করে। (এবং ==এগুলিকে আলাদা করতে পারবেন না কারণ অপ্টিমাইজার তুলনাটি অপ্টিমাইজ করে না))


এখন তুলনা করুন 3.6:

>>> dis.dis('True == 1')
  1           0 LOAD_CONST               0 (True)
              2 LOAD_CONST               1 (1)
              4 COMPARE_OP               2 (==)
              6 RETURN_VALUE

>>> dis.dis('True + True')
  1           0 LOAD_CONST               1 (2)
              2 RETURN_VALUE

এখানে, এটি একটি emitting এর LOAD_CONST (True)কীওয়ার্ডটি যা অপটিমাইজার জন্য করতে সুবিধা নেওয়ার জন্য। সুতরাং, পার্থক্য True + 1 না , ঠিক একই কারণে while Trueনা। (এবং ==এখনও তাদের পার্থক্য করে না কারণ অপ্টিমাইজার তুলনাটি অপ্টিমাইজ করে না))


এদিকে, কোডটি অপ্টিমাইজ না করা থাকলে, দোভাষী তার চিকিত্সা শেষ করে Trueএবং 1এই তিনটি ক্ষেত্রেই ঠিক একই রকম হয়। boolএর একটি উপশ্রেণী int, এবং এর বেশিরভাগ পদ্ধতির উত্তরাধিকার সূত্রে প্রাপ্ত হয় intএবং Trueএর অভ্যন্তরীণ পূর্ণ মান 1 হয় 1. সুতরাং, আপনি কোনও whileপরীক্ষা করছেন কিনা ( __bool__3.x এ, __nonzero__2.x তে), তুলনা ( __eq__) বা পাটিগণিত ( __add__), আপনি একই পদ্ধতিটি কল করছেন যা আপনি ব্যবহার করেন Trueবা না করেন 1

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.