পাইথন স্ট্রিং ইন্টার্নিং


92

যদিও এই প্রশ্নের অনুশীলনে বাস্তবে কোনও ব্যবহার নেই, তবে পাইথন কীভাবে স্ট্রিং ইন্টার্নিং করে তা সম্পর্কে আমি আগ্রহী। আমি নিম্নলিখিতটি লক্ষ্য করেছি।

>>> "string" is "string"
True

আমার প্রত্যাশা অনুযায়ী এটি

আপনি এটি করতে পারেন।

>>> "strin"+"g" is "string"
True

এবং এটি বেশ চালাক!

তবে আপনি এটি করতে পারবেন না।

>>> s1 = "strin"
>>> s2 = "string"
>>> s1+"g" is s2
False

পাইথন কেন মূল্যায়ন করবে না s1+"g"এবং বুঝতে পারে যে এটি একইরকম s2এবং একই ঠিকানার দিকে এটি নির্দেশ করবে? এটি ফিরে আসার জন্য সেই শেষ ব্লকে আসলে কী চলছে False?

উত্তর:


95

এটি বাস্তবায়ন-নির্দিষ্ট, তবে আপনার অনুবাদক সম্ভবত কমপাইল-টাইম ধ্রুবকগুলিকে সংযুক্ত করছেন তবে রান-টাইম এক্সপ্রেশনগুলির ফলাফল নয়।

এরপরে আমি সিপিথন ২.7.৩ ব্যবহার করি।

দ্বিতীয় উদাহরণে, "strin"+"g"সংকলন সময়ে এক্সপ্রেশনটি মূল্যায়ন করা হয় এবং এর সাথে প্রতিস্থাপিত হয় "string"। এটি প্রথম দুটি উদাহরণ একই আচরণ করে।

যদি আমরা বাইকোডগুলি পরীক্ষা করি তবে আমরা দেখতে পাবো যে সেগুলি হুবহু এক:

  # s1 = "string"
  2           0 LOAD_CONST               1 ('string')
              3 STORE_FAST               0 (s1)

  # s2 = "strin" + "g"
  3           6 LOAD_CONST               4 ('string')
              9 STORE_FAST               1 (s2)

তৃতীয় উদাহরণটি একটি রান-টাইম কনটেন্টেশন জড়িত, যার ফলাফল স্বয়ংক্রিয়ভাবে অভ্যন্তরীণ হয় না:

  # s3a = "strin"
  # s3 = s3a + "g"
  4          12 LOAD_CONST               2 ('strin')
             15 STORE_FAST               2 (s3a)

  5          18 LOAD_FAST                2 (s3a)
             21 LOAD_CONST               3 ('g')
             24 BINARY_ADD          
             25 STORE_FAST               3 (s3)
             28 LOAD_CONST               0 (None)
             31 RETURN_VALUE        

আপনি যদি ম্যানুয়ালি intern()তৃতীয় অভিব্যক্তির ফলাফল হয়ে থাকেন তবে আপনি আগের মতো একই বস্তুটি পেয়ে যাবেন:

>>> s3a = "strin"
>>> s3 = s3a + "g"
>>> s3 is "string"
False
>>> intern(s3) is "string"
True

22
এবং রেকর্ড করুন: পাইথন এর চিঁ চিঁ-গহ্বর অপ্টিমাইজেশান প্রাক ক্যালকুলেট ধ্রুবক (চালু গাণিতিক অপারেশন হবে "string1" + "s2", 10 + 3*20ইত্যাদি) কম্পাইল সময়, কিন্তু এর ফলে সীমা সিকোয়েন্স মাত্র 20 উপাদান (প্রতিরোধ [None] * 10**1000মাত্রাতিরিক্ত আপনার বাইটকোড বিস্তৃত থেকে)। এটি এই অপটিমাইজেশন যা ধসে "strin" + "g"পড়ে "string"; ফলাফলটি 20 টির চেয়ে কম সংখ্যক।
মার্টিজন পিটারস

13
এবং এটি দ্বিগুণভাবে পরিষ্কার করার জন্য: এখানে মোটেই ইন্টার্নিং চলছে না। অপরিবর্তনীয় আক্ষরিক পরিবর্তে বাইটোকোড সহ ধ্রুবক হিসাবে সংরক্ষণ করা হয়। Interning নেই কোডে ব্যবহৃত নামের জন্য সঞ্চালিত, কিন্তু না প্রোগ্রাম দ্বারা নির্মিত স্ট্রিং মানের জন্য যদি না বিশেষভাবে দ্বারা অন্তরীণ intern()ফাংশন।
মার্টিজান পিটারস

9
যারা, যারা খোঁজ করে জন্য internপাইথন 3 ফাংশন - এটি চলে যায় sys.intern
Timofey Chernousov

1

মামলা 1

>>> x = "123"  
>>> y = "123"  
>>> x == y  
True  
>>> x is y  
True  
>>> id(x)  
50986112  
>>> id(y)  
50986112  

মামলা 2

>>> x = "12"
>>> y = "123"
>>> x = x + "3"
>>> x is y
False
>>> x == y
True

এখন, আপনার প্রশ্ন কেন আইডি ক্ষেত্রে 1 সমান এবং কেস 2. নয়
কেস 1, আপনি আক্ষরিক একটি স্ট্রিং নির্ধারিত আছে "123"করতে xএবং y

যেহেতু স্ট্রিং অপরিবর্তনীয়, দোভাষীর পক্ষে স্ট্রিংকে কেবল একবার আক্ষরিক স্টোর করার জন্য এবং সমস্ত ভেরিয়েবলগুলি একই বস্তুর দিকে চিহ্নিত করার জন্য এটি বোধগম্য হয়।
সুতরাং আপনি আইডিটিকে অভিন্ন হিসাবে দেখেন see

ক্ষেত্রে 2, আপনি সংক্ষিপ্তকরণ xব্যবহার করে সংশোধন করছেন। উভয় xএবং yএকই মান আছে, কিন্তু একই পরিচয় নয়।
উভয়ই স্মৃতিতে বিভিন্ন বস্তুগুলিকে নির্দেশ করে। অতএব তাদের আলাদা আছে idএবং isঅপারেটর ফিরে এসেছেFalse


কীভাবে আসবেন, যেহেতু স্ট্রিংগুলি অপরিবর্তনীয়, এক্স + "3" বরাদ্দ করা (এবং স্ট্রিংটি সংরক্ষণ করার জন্য একটি নতুন স্পট সন্ধান করা) y এর মতো একই রেফারেন্সকে বরাদ্দ করে না?
নিকচেক

কারণ তখন এটি সমস্ত বিদ্যমান স্ট্রিংয়ের সাথে নতুন স্ট্রিংটির তুলনা করা প্রয়োজন; সম্ভাব্য একটি খুব ব্যয়বহুল অপারেশন। স্মৃতি হ্রাস করার জন্য, আমি মনে করি যে অ্যাসাইনমেন্টের পরে এটি ব্যাকগ্রাউন্ডে এটি করতে পারে তবে আপনি এমনকি অপরিচিত আচরণের সাথে শেষ করবেন: id(x) != id(x)উদাহরণস্বরূপ, কারণ স্ট্রিংটি মূল্যায়নের প্রক্রিয়াতে স্থানান্তরিত হয়েছিল।
ডিলানইং

4
@ আন্ড্রেআকন্টে কারণ স্ট্রিংস কনটেনটেশন প্রতিবার নতুন একটি উত্পন্ন করার জন্য ব্যবহৃত স্ট্রিংগুলির পুলটিতে সন্ধানের অতিরিক্ত কাজ করে না। অন্যদিকে, অনুবাদক অভিব্যক্তি "সেরা অনুকূল রূপ" x = "12" + "3"মধ্যে x = "123"(ক একক অভিব্যক্তি দুটি স্ট্রিং লিটারেল এর সংযুক্তকরণের) যাতে নিয়োগ আসলে লুকআপ আছে এবং জন্য সমান "অভ্যন্তরীণ" STRING খুঁজে বের করে y = "123"
ডেরেনিও

প্রকৃতপক্ষে, এটি নয় যে অ্যাসাইনমেন্টটি সোর্স কোড থেকে প্রতিটি স্ট্রিং আক্ষরিক চেয়ে "অভ্যন্তরীণ" হয়ে যায় এবং সেই বস্তুটি অন্য সমস্ত জায়গায় পুনরায় ব্যবহৃত হয়ে যায় than
ডেরেনিও
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.