পাইথন কোড কেন দৈর্ঘ্যের পদ্ধতির পরিবর্তে লেন () ফাংশন ব্যবহার করে?


204

আমি জানি যে পাইথনের একটি len()ফাংশন রয়েছে যা স্ট্রিংয়ের আকার নির্ধারণ করতে ব্যবহৃত হয় তবে আমি ভাবছিলাম কেন এটি স্ট্রিং অবজেক্টের কোনও পদ্ধতি নয়।

হালনাগাদ

ঠিক আছে, আমি বুঝতে পেরেছিলাম যে আমি বিব্রতকরভাবে ভুল হয়ে গিয়েছিলাম। __len__()আসলে একটি স্ট্রিং অবজেক্টের একটি পদ্ধতি। স্ট্রিং অবজেক্টে লেন ফাংশনটি ব্যবহার করে পাইথনে অবজেক্ট অরিয়েন্টেড কোডটি দেখতে কেবল অদ্ভুত বলে মনে হচ্ছে। তদুপরি, __len__কেবল লেনের পরিবর্তে নাম হিসাবে দেখা খুব অদ্ভুত ।

উত্তর:


180

স্ট্রিংগুলির দৈর্ঘ্যের পদ্ধতি রয়েছে: __len__()

পাইথনের প্রোটোকলটি হ'ল অবজেক্টগুলিতে এই পদ্ধতিটি প্রয়োগ করা হবে যার দৈর্ঘ্য রয়েছে এবং বিল্ট-ইন len()ফাংশনটি ব্যবহার করা হবে, যা আপনাকে __iter__()বিল্ট-ইন iter()ফাংশনটি প্রয়োগ ও ব্যবহার করার পদ্ধতিটির অনুরূপ বলে দেয় (বা পদ্ধতিটি পিছনে ডেকে আনে) আপনার জন্য দৃশ্যগুলি) এমন জিনিসগুলিতে যা পুনরাবৃত্তিযোগ্য।

দেখুন এমুলেট ধারক ধরনের আরও তথ্যের জন্য।

পাইথনের প্রোটোকল বিষয়টিতে এখানে একটি ভাল পড়ুন: পাইথন এবং সর্বনিম্ন বিস্ময়ের মূলনীতি


124
এটি আমাকে অবাক করে দেয় যে ব্যবহারের কারণটি কতটা মুরোনিক len। তারা মনে করেন যে বাস্তবায়নে বাধ্য করার .__len__চেয়ে মানুষকে প্রয়োগ করতে বাধ্য করা আরও সহজ .len()। এটি একই জিনিস এবং একটিকে আরও পরিষ্কার পরিচ্ছন্ন দেখাচ্ছে। যদি ভাষাটির একটি ওওপি হতে চলেছে __len__তবে বিশ্বে কী তৈরি করা যায়len(..)
বিকল্পটি

38
লেন, স্টার, ইত্যাদি মানচিত্র, হ্রাস, এবং ফিল্টার কেবল কোনও পদ্ধতি কল করার জন্য কোনও ফাংশন বা ল্যাম্বডাকে সংজ্ঞায়িত করার প্রয়োজন ছাড়াই উচ্চতর অর্ডার ফাংশনগুলির সাথে ব্যবহার করা যেতে পারে। পাইপনে এমনকি সমস্ত কিছু ওওপি-র চারদিকে ঘোরে না।
এভিকাটোস

11
এছাড়াও, একটি প্রোটোকল ব্যবহার করে, তারা জিনিসগুলি বাস্তবায়নের বিকল্প উপায় সরবরাহ করতে পারে। উদাহরণস্বরূপ, আপনি একটি __iter__বা কেবল সহ একটি পুনরাবৃত্তিযোগ্য তৈরি করতে পারেন __getitem__এবং iter(x)যে কোনও উপায়ে কাজ করবেন। আপনি __bool__বা এর সাথে ব্যবহারযোগ্য ইন-বুল-প্রসঙ্গ অবজেক্ট তৈরি করতে পারেন __len__এবং bool(x)যে কোনও উপায়ে কাজ করবেন। ইত্যাদি। আমি আরমিন লিঙ্ক পোস্ট কিন্তু যুক্তিসঙ্গতভাবে ভাল এই ব্যাখ্যা না তিনি কি এমনকি যদি, একটি লোক যারা প্রায়ই কোর devs সঙ্গে মতভেদ প্রকাশ্যে এর দ্বারা একটি বাহিরে ব্যাখ্যার কারণ ক্যাবলা পাইথন কলিং ঠিক ন্যায্য হবে না ... মনে
abarnert

8
@ এভিকাটোস: "ওওপিতে সমস্ত কিছু ঘুরে না" এর জন্য +1, তবে আমি " বিশেষত পাইথনে" এমনকি শেষ না করেই শেষ করব । পাইথন (জাভা, রুবি বা স্মার্টটাকের বিপরীতে) "খাঁটি ওওপি" ভাষা হওয়ার চেষ্টা করে না; এটি স্পষ্টভাবে একটি "বহু-দৃষ্টান্ত" ভাষা হিসাবে তৈরি করা হয়েছে। তালিকার বোধগম্য পুনরাবৃত্তির উপর পদ্ধতি নয়। zipএকটি শীর্ষ-স্তরের ফাংশন, কোনও zip_withপদ্ধতি নয়। ইত্যাদি। সমস্ত কিছু কেবল একটি বস্তু হওয়ায় এর অর্থ এই নয় যে প্রতিটি জিনিস সম্পর্কে সর্বাধিক গুরুত্বপূর্ণ বিষয় thing
অবসর

7
এই নিবন্ধটি খুব খারাপভাবে লেখা হয়েছে এটি পড়ার চেষ্টা করার পরে আমি বিভ্রান্ত এবং ক্ষুব্ধ বোধ করি। "পাইথন ২.x তে টুপল টাইপ উদাহরণস্বরূপ কোনও অ-বিশেষ পদ্ধতি প্রকাশ করে না এবং তবুও আপনি এটিকে একটি স্ট্রিং তৈরি করতে ব্যবহার করতে পারেন:" পুরো জিনিসটি নিকট-অনিবার্য বাক্যগুলির সংমিশ্রণ।
মিররফেটে

93

জিম এর উত্তর এই প্রশ্নের সাহায্য করতে পারে; আমি এখানে এটি অনুলিপি। গাইডের ভ্যান রসমের উদ্ধৃতি:

প্রথমত, আমি এইচসিআই কারণে (ডিএফ __len __ () পরে এসেছি) x.len () এর চেয়ে বেশি লেন (এক্স) বেছে নিয়েছি। দুটি আন্তঃসংযোগযুক্ত কারণ রয়েছে, উভয়ই এইচসিআই:

(ক) কিছু ক্রিয়াকলাপের জন্য, উপসর্গ শিরোনাম পোস্টফিক্সের চেয়ে ভাল পড়ে - উপসর্গ (এবং ইনফিক্স!) অপারেশনগুলির গণিতে একটি দীর্ঘ traditionতিহ্য রয়েছে যা স্বাক্ষরগুলি পছন্দ করে যেখানে ভিজ্যুয়ালগুলি কোনও সমস্যা সম্পর্কে গণিতবিদকে ভাবতে সহায়তা করে। আমরা সহজেই তুলনা করুন যার সাথে আমরা x * (a + b) এর মতো সূত্রটি x এ আবার লিখি একটি + X একটি কাঁচা OO যেমন পণ্য স্বরলিপি ব্যবহার করে একই জিনিস করছেন জবরজঙ্গতা বি।

(খ) আমি যখন লেন (x) বলে কোড পড়ি তখন আমি জানি যে এটি কোনও কিছুর দৈর্ঘ্যের জন্য জিজ্ঞাসা করছে। এটি আমাকে দুটি জিনিস বলে: ফলাফলটি একটি পূর্ণসংখ্যা এবং যুক্তিটি এক ধরণের ধারক। বিপরীতভাবে, যখন আমি x.len () পড়ি, আমাকে ইতিমধ্যে জানতে হবে যে এক্স হ'ল এক ধরণের ধারক যা একটি ইন্টারফেস প্রয়োগ করে বা শ্রেণীর উত্তরাধিকার সূত্রে একটি স্ট্যান্ডার্ড লেন () থাকে। আমাদের মাঝে মাঝে যে বিভ্রান্তি রয়েছে তা প্রত্যক্ষ করুন যখন ম্যাপিং বাস্তবায়ন না করে এমন কোনও শ্রেণীর একটি get () বা কী () পদ্ধতি থাকে বা কোনও ফাইল যা ফাইল নয় তার লেখার পদ্ধতি থাকে।

একই কথা অন্যভাবে বলছি, আমি বিল্ট-ইন অপারেশন হিসাবে 'লেন' দেখছি। আমি এটি হারাতে ঘৃণা করব। / ... /


37

একটি lenপদ্ধতি আছে:

>>> a = 'a string of some length'
>>> a.__len__()
23
>>> a.__len__
<method-wrapper '__len__' of str object at 0x02005650>

34

পাইথন একটি বাস্তবমুখী প্রোগ্রামিং ভাষা, এবং কারণ len()একটি ফাংশন এবং একটি পদ্ধতি হচ্ছে str, list, dictইত্যাদি বাস্তবমুখী হয়।

len()বিল্ট-ইন ফাংশন পুলিশ সরাসরি বিল্ট-ইন ধরনের: এর CPython বাস্তবায়ন len()আসলে ফেরৎ মান ob_sizeমাঠে PyVarObjectসি struct যে প্রতিনিধিত্ব করে কোনো পরিবর্তনশীল আকারের বিল্ট ইন মেমরি বস্তুর। এটি কোনও পদ্ধতিতে কল করার চেয়ে অনেক দ্রুত - কোনও অ্যাট্রিবিউট লুকআপ হওয়ার দরকার নেই। একটি সংগ্রহে আইটেম সংখ্যা পথ একটি সাধারণ অপারেশন এবং যেমন মৌলিক এবং বৈচিত্র্যময় ধরনের জন্য দক্ষতার সঙ্গে কাজ করতে হবে str, list, array.arrayইত্যাদি

তবে, ধারাবাহিকতা প্রচার করতে, যখন len(o)কোনও ব্যবহারকারী-সংজ্ঞায়িত প্রকারে প্রয়োগ করা হয়, পাইথন ফ্যালব্যাক o.__len__()হিসাবে কল করে । __len__, __abs__এবং পাইথন ডেটা মডেলটিতে নথিভুক্ত অন্যান্য সমস্ত বিশেষ পদ্ধতিগুলি বিল্ট-ইনগুলির মতো আচরণ করে এমন অবজেক্ট তৈরি করা সহজ করে তোলে যা আমরা "পাইথোনিক" নামে অভিহিত করি এবং সংবেদনশীল এবং অত্যন্ত সামঞ্জস্যপূর্ণ এপিআইগুলি সক্ষম করে।

বিশেষ পদ্ধতি প্রয়োগ করে আপনার বস্তুগুলি পুনরাবৃত্তি, ওভারলোড ইনফিক্স অপারেটরগুলি, withব্লকগুলিতে প্রসঙ্গগুলি পরিচালনা করতে পারে।

দ্বিতীয় কারণটা মত গাইডো van Rossum থেকে কোট দ্বারা সমর্থিত এই এক , এটা সহজ যে পড়তে ও লিখতে হয় len(s)চেয়েs.len()

স্বরলিপিটি len(s)প্রিফিক্স নোটেশন সহ অ্যানারি অপারেটরের সাথে সামঞ্জস্যপূর্ণ, যেমন abs(n)len()এর চেয়ে বেশি বার ব্যবহার করা হয় abs()এবং এটি লেখার মতো সহজ হওয়ার দাবি রাখে।

এর একটি historicalতিহাসিক কারণও থাকতে পারে: পাইথনের পূর্ববর্তী এবিসি ভাষায় (এবং এর নকশায় খুব প্রভাবশালী ছিল), সেখানে একটি অদ্বিতীয় অপারেটর লেখা ছিল #sযার অর্থ ছিল len(s)


12
met% python -c 'import this' | grep 'only one'
There should be one-- and preferably only one --obvious way to do it.

34
একটি বস্তুর সাথে কাজ করার সময় স্পষ্ট জিনিসটি অবশ্যই একটি পদ্ধতি।
পিটার কুপার

4
@ পিটার: আমি এমন কোনও ব্যক্তিকে ফটো প্রমান সহ ২০ ডলার দিয়ে দেবো যে তারা আপনার মন্তব্যটি গিডোর পিঠে চাপিয়ে দিয়েছে। His 50 যদি এটি তার কপালে থাকে।
বাগ

1
হ্যাঁ, পাইথন ডিজাইনাররা ডগমাকে মেনে চলে তবে তারা নিজেরাই নিজের ডগমাকে সম্মান করে না।
বিটেক

2
y পাইথন-সি 'এটি আমদানি করুন' | স্পষ্টভাবে
এড র্যান্ডাল

4

এখানে কিছু দুর্দান্ত উত্তর রয়েছে, এবং তাই আমি নিজের নিজের দেওয়ার আগে আমি কয়েকটি রত্ন হাইলাইট করতে চাই (কোনও রুবি পাং উদ্দেশ্য নয়) আমি এখানে পড়েছি।

  • পাইথন একটি খাঁটি ওওপি ভাষা নয় - এটি একটি সাধারণ উদ্দেশ্য, বহু-দৃষ্টান্তের ভাষা যা প্রোগ্রামারকে তারা সবচেয়ে স্বাচ্ছন্দ্যযুক্ত দৃষ্টান্ত এবং / অথবা তাদের সমাধানের জন্য সবচেয়ে উপযুক্ত উপমা ব্যবহার করতে দেয়।
  • পাইথনের প্রথম শ্রেণির ফাংশন রয়েছে, সুতরাং lenএটি আসলে একটি বস্তু। অন্যদিকে রুবিতে প্রথম শ্রেণির ফাংশন নেই। সুতরাং lenফাংশন অবজেক্টের নিজস্ব পদ্ধতি রয়েছে যা আপনি চালিয়ে পরীক্ষা করতে পারবেন dir(len)

আপনি যদি নিজের কোডে এইভাবে কাজ করেন তা পছন্দ না করেন তবে আপনার পছন্দসই পদ্ধতিটি ব্যবহার করে পাত্রে পুনরায় প্রয়োগ করা আপনার পক্ষে নগণ্য (

>>> class List(list):
...     def len(self):
...         return len(self)
...
>>> class Dict(dict):
...     def len(self):
...         return len(self)
...
>>> class Tuple(tuple):
...     def len(self):
...         return len(self)
...
>>> class Set(set):
...     def len(self):
...         return len(self)
...
>>> my_list = List([1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'])
>>> my_dict = Dict({'key': 'value', 'site': 'stackoverflow'})
>>> my_set = Set({1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'})
>>> my_tuple = Tuple((1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'))
>>> my_containers = Tuple((my_list, my_dict, my_set, my_tuple))
>>>
>>> for container in my_containers:
...     print container.len()
...
15
2
15
15

0

আপনি বলতে পারেন

>> x = 'test'
>> len(x)
4

পাইথন ২.7.৩ ব্যবহার করে।


9
lenফাংশন ইতিমধ্যে আগের উত্তর উল্লেখ করা হয়েছিল। তাহলে এই "উত্তর" এর মূল বক্তব্য কী?
পাইটর ডব্রোগস্ট

0

এখানে বাকি উত্তরগুলির থেকে কিছু অনুপস্থিত: lenফাংশনটি পরীক্ষা করে যে __len__পদ্ধতিটি একটি অ-নেতিবাচককে ফিরিয়ে দেয় int। সত্য যে lenএকটি ফাংশন মানে যে শ্রেণীর এই আচরণ ওভাররাইড করতে পারবে না চেক এড়ানো। এই হিসাবে, len(obj)সুরক্ষা যে একটি স্তর দেয়obj.len() পারে না।

উদাহরণ:

>>> class A:
...     def __len__(self):
...         return 'foo'
...
>>> len(A())
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    len(A())
TypeError: 'str' object cannot be interpreted as an integer
>>> class B:
...     def __len__(self):
...         return -1
... 
>>> len(B())
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    len(B())
ValueError: __len__() should return >= 0

অবশ্যই, lenফাংশনটিকে বৈশ্বিক পরিবর্তনশীল হিসাবে পুনরায় নিয়োগের মাধ্যমে "ওভাররাইড" করা সম্ভব , তবে কোডটি কোনও শ্রেণীর কোনও পদ্ধতিকে ওভাররাইড করে এমন কোডের চেয়ে অনেক স্পষ্টতই সন্দেহজনক।


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