পাইথনের লুকানো বৈশিষ্ট্য [বন্ধ]


1419

পাইথন প্রোগ্রামিং ভাষার কম জ্ঞাত তবে দরকারী বৈশিষ্ট্যগুলি কী কী?

  • পাইথন কোরটিতে উত্তর সীমাবদ্ধ করার চেষ্টা করুন।
  • উত্তর প্রতি বৈশিষ্ট্য।
  • কেবলমাত্র ডকুমেন্টেশনের লিঙ্ক নয়, বৈশিষ্ট্যের একটি উদাহরণ এবং সংক্ষিপ্ত বিবরণ দিন।
  • প্রথম লাইন হিসাবে একটি শিরোনাম ব্যবহার করে বৈশিষ্ট্যটিকে লেবেল করুন।

উত্তরের দ্রুত লিঙ্কগুলি:

উত্তর:


740

চেইনিং তুলনা অপারেটর:

>>> x = 5
>>> 1 < x < 10
True
>>> 10 < x < 20 
False
>>> x < 10 < x*10 < 100
True
>>> 10 > x <= 9
True
>>> 5 == x > 4
True

আপনি যদি ভাবছেন যে এটি করছে 1 < x, যা হিসাবে প্রকাশিত হয় Trueএবং তারপরে তুলনা করা হয় True < 10যা হ'ল True, তবে না, যা ঘটেছিল তা আসলেই হয় না (শেষ উদাহরণটি দেখুন)) এটি সত্যই অনুবাদ করা হচ্ছে 1 < x and x < 10, এবং x < 10 and 10 < x * 10 and x*10 < 100, তবে কম টাইপিং এবং প্রতিটি সহ শব্দটি কেবল একবার মূল্যায়ন করা হয়।


121
এটা খুব সহায়ক। এটি সমস্ত ভাষার জন্য মানক হওয়া উচিত। দুঃখের বিষয়, এটা না।
stale ব্যাখ্যাzel

8
আপনার এমন কিছু উদাহরণ যুক্ত করা উচিত যা প্রত্যাবর্তন করতে পারে। যেমন >>> 10 <x <20 মিথ্যা
জুতার লব

19
এটি অন্যান্য তুলনামূলক অপারেটরগুলিতেও প্রযোজ্য, এ কারণেই লোকেরা কখনও কখনও অবাক হয় কেন (5 এর মধ্যে [5] সত্য) মিথ্যা (তবে শুরু করার মতো বুলিয়ানগুলির বিরুদ্ধে স্পষ্টভাবে পরীক্ষা করা অবাস্তব)।
মাইলস

19
ভাল তবে সমান অগ্রাধিকারের জন্য নজর রাখুন, যেমন 'ইন' এবং '='। 'এ ইন বি == ডি ইন ডি' এর অর্থ '(এ ইন বি) এবং (বি == সি) এবং (ডি ইন সি)' যা অপ্রত্যাশিত হতে পারে।
চার্লস মেরিয়ামিয়াম

15
আজাফ: লিস্পের তুলনাগুলি প্রাকৃতিকভাবে এইভাবে কাজ করে। এটি কোনও বিশেষ ক্ষেত্রে নয় কারণ ব্যাখ্যা করার মতো অন্য কোনও (যুক্তিসঙ্গত) উপায় নেই (< 1 x 10)। আপনি তাদের একক যুক্তিতে প্রয়োগ করতে পারেন, যেমন (= 10): cs.cmu.edu/Groups/AI/html/hyperspec/HyperSpec/Body/…
কেন

512

আপনার রেজেক্সটি ডিবাগ করার জন্য পাইথন রেজেক্স পার্স ট্রি পান।

নিয়মিত প্রকাশগুলি অজগরটির একটি দুর্দান্ত বৈশিষ্ট্য, তবে এগুলি ডিবাগ করা একটি ব্যথা হতে পারে এবং একটি রেজেক্স ভুল পাওয়া খুব সহজ।

ভাগ্যক্রমে, অজগরটি অননুমোদিত, পরীক্ষামূলক, লুকানো পতাকা re.DEBUG(প্রকৃতপক্ষে, 128) থেকে পেরিয়ে রেজেক্স পার্স গাছ মুদ্রণ করতে পারে re.compile

>>> re.compile("^\[font(?:=(?P<size>[-+][0-9]{1,2}))?\](.*?)[/font]",
    re.DEBUG)
at at_beginning
literal 91
literal 102
literal 111
literal 110
literal 116
max_repeat 0 1
  subpattern None
    literal 61
    subpattern 1
      in
        literal 45
        literal 43
      max_repeat 1 2
        in
          range (48, 57)
literal 93
subpattern 2
  min_repeat 0 65535
    any None
in
  literal 47
  literal 102
  literal 111
  literal 110
  literal 116

সিনট্যাক্সটি একবার বুঝতে পারলে আপনি নিজের ত্রুটিগুলি চিহ্নিত করতে পারেন। সেখানে আমরা দেখতে পাচ্ছি যে আমি []ভিতরে পালাতে ভুলে গেছি [/font]

অবশ্যই আপনি এটিকে আপনার পছন্দসই পতাকাগুলির সাথে সংযুক্ত করতে পারেন, যেমন মন্তব্য করা রেজিক্সগুলি:

>>> re.compile("""
 ^              # start of a line
 \[font         # the font tag
 (?:=(?P<size>  # optional [font=+size]
 [-+][0-9]{1,2} # size specification
 ))?
 \]             # end of tag
 (.*?)          # text between the tags
 \[/font\]      # end of the tag
 """, re.DEBUG|re.VERBOSE|re.DOTALL)

3
নিয়মিত এক্সপ্রেশন ব্যবহার করে এইচটিএমএল পার্স করা ব্যতীত ধীর এবং বেদনাদায়ক। এমনকি বিল্ট-ইন 'এইচটিএমএল' পার্সার মডিউলটি কাজটি পেতে রেজিেক্সগুলি ব্যবহার করে না। এবং যদি এইচটিএমএল মডিউলটি আপনাকে সন্তুষ্ট না করে তবে প্রচুর পরিমাণে এক্সএমএল / এইচটিএমএল পার্সার মডিউল রয়েছে যা চক্রটি পুনরায় উদ্ভাবন না করেই কাজটি করে।
BatchyX

আউটপুট সিনট্যাক্সে ডকুমেন্টেশনের একটি লিঙ্ক দুর্দান্ত হবে।
ব্যক্তি

1
এটি পাইথনের একটি আনুষ্ঠানিক অংশ হওয়া উচিত, পরীক্ষামূলক নয় ... RegEx সর্বদা কৌতুকপূর্ণ এবং যা ঘটছে তা সন্ধান করতে সক্ষম হওয়া সত্যিই সহায়ক।
Cahit

460

গোনা

গণনা সহ একটি পুনরাবৃত্তযোগ্য মোড়ানো এবং এটি সূচক সহ আইটেমটি উপার্জন করবে।

উদাহরণ স্বরূপ:


>>> a = ['a', 'b', 'c', 'd', 'e']
>>> for index, item in enumerate(a): print index, item
...
0 a
1 b
2 c
3 d
4 e
>>>

তথ্যসূত্র:


56
আমি আশ্চর্য হয়েছি যে পাইথন তালিকার বিষয়ে টিউটোরিয়ালে এটি নিয়মিতভাবে কভার করা হয়নি।
ড্রিমন

45
এবং এই সমস্ত সময় আমি এইভাবে কোডিং করছি: আমি সীমার জন্য (লেন (ক)): ... এবং তারপরে বর্তমান আইটেমটি পেতে একটি [i] ব্যবহার করছি।
ফার্নান্দো মার্টিন

4
@ বেরি সাকালা: আমার জানা মতে, এটি অবহেলা করা হয়নি।
জ্যাব

23
পবিত্র বোকা এটি দুর্দান্ত। আমি এক্সরেঞ্জের জন্য (লেন (ক)): বরাবরই আমার সর্বকালের প্রিয় পাইথন আইডিয়াম।
ব্যক্তি

15
গণনাটি স্বেচ্ছাসেবী সূচক থেকে শুরু করা যেতে পারে, প্রয়োজন নেই 0 উদাহরণ: 'আমার জন্য,
গণিতে

419

জেনারেটর অবজেক্ট তৈরি করা হচ্ছে

যদি লিখি

x=(n for n in foo if bar(n))

আপনি জেনারেটরটি বের করতে পারেন এবং এটি এক্সকে নির্ধারণ করতে পারেন। এখন এর অর্থ আপনি করতে পারেন

for n in x:

এর সুবিধাটি হ'ল আপনার মধ্যবর্তী স্থানের দরকার নেই যা আপনি যদি করেন তবে আপনার প্রয়োজন হবে

x = [n for n in foo if bar(n)]

কিছু ক্ষেত্রে এটি উল্লেখযোগ্য গতি বাড়িয়ে তুলতে পারে।

জেনারেটরের শেষের দিকে বিবৃতিগুলি মূলত লুপগুলির জন্য নেস্টেড প্রতিলিপি করা হলে আপনি অনেকগুলি সংযুক্ত করতে পারেন:

>>> n = ((a,b) for a in range(0,2) for b in range(4,6))
>>> for i in n:
...   print i 

(0, 4)
(0, 5)
(1, 4)
(1, 5)

আপনি এটির জন্য নেস্টেড তালিকার উপলব্ধিটিও ব্যবহার করতে পারেন, হ্যাঁ?
shapr

54
বিশেষ দ্রষ্টব্য হ'ল মেমরির ওভারহেড সঞ্চয়। মানগুলি চাহিদা অনুযায়ী গণনা করা হয়, সুতরাং আপনার মেমরিতে তালিকার বোধগম্যের পুরো ফলাফল কখনই না থাকে। আপনি যদি পরে তালিকা বোধের কেবলমাত্র অংশে পুনরাবৃত্তি করেন তবে এটি বিশেষত কাম্য।
saffsd

19
এটি বিশেষত "লুকানো" ইমো নয়, তবে এটিও লক্ষ্যণীয় যে আপনি কোনও জেনারেটর বস্তুটি রিভাইন্ড করতে পারেননি, আপনি কোনও তালিকাতে বহুবার পুনরাবৃত্তি করতে পারেন।
26 এ এসএমএস করেছে

13
জেনারেটরের "নো রিওয়াইন্ড" বৈশিষ্ট্যটি কিছু বিভ্রান্তির কারণ হতে পারে। বিশেষত, আপনি যদি ডিবাগিংয়ের জন্য কোনও জেনারেটরের সামগ্রী মুদ্রণ করেন, তবে ডেটা প্রক্রিয়া করার জন্য এটি পরে ব্যবহার করুন, এটি কার্যকর হয় না। ডেটা উত্পাদিত হয়, মুদ্রণ () দ্বারা গ্রাস করা হয়, তবে সাধারণ প্রসেসিংয়ের জন্য উপলব্ধ হয় না। এগুলি বোঝার তালিকার জন্য প্রযোজ্য নয়, যেহেতু তারা সম্পূর্ণ স্মৃতিতে সঞ্চিত রয়েছে।
jhntellsall

4
অনুরূপ (ডুপ?) উত্তর: stackoverflow.com/questions/101268/hided-features-of-python/… দ্রষ্টব্য, তবে আমি যে উত্তরটি এখানে সংযুক্ত করেছি তাতে জেনারেটরের শক্তি সম্পর্কে একটি সত্যই ভাল উপস্থাপনা উল্লেখ রয়েছে। আপনার সত্যই এটি পরীক্ষা করা উচিত।
ডেনিলসন সা মিয়া

353

iter () কলযোগ্য আর্গুমেন্ট নিতে পারে

এই ক্ষেত্রে:

def seek_next_line(f):
    for c in iter(lambda: f.read(1),'\n'):
        pass

iter(callable, until_value)ফাংশন বারবার আহ্বান callableএবং তার ফলাফলের উৎপাদ পর্যন্ত until_valueফিরিয়ে দেওয়া হয়।


পাইথনের নবাগত হিসাবে, আপনি দয়া করে lambdaএখানে কীওয়ার্ডটি প্রয়োজনীয় কেন তা ব্যাখ্যা করতে পারেন ?
সিজেএক্স

ল্যাম্বডা ছাড়াই @ সিজেএক্স, এফ ফাংশনে যাওয়ার আগে f.read (1) মূল্যায়ন করা হবে (স্ট্রিং ফিরিয়ে দেওয়া)। পরিবর্তে, ল্যাম্বদা একটি বেনামে ফাংশন তৈরি করে এবং এটির কাছে চলে যায়।
jmilloy

339

পরিবর্তনীয় ডিফল্ট যুক্তিগুলির সাথে সতর্ক থাকুন

>>> def foo(x=[]):
...     x.append(1)
...     print x
... 
>>> foo()
[1]
>>> foo()
[1, 1]
>>> foo()
[1, 1, 1]

পরিবর্তে, আপনাকে "প্রদত্ত নয়" নির্দেশ করে একটি সেন্ডিনেল মান ব্যবহার করা উচিত এবং আপনি যে পরিবর্তনীয় পরিবর্তনটি ডিফল্ট হিসাবে চান তা প্রতিস্থাপন করুন:

>>> def foo(x=None):
...     if x is None:
...         x = []
...     x.append(1)
...     print x
>>> foo()
[1]
>>> foo()
[1]

39
এটি অবশ্যই আরও কদর্য লুকানো বৈশিষ্ট্যগুলির মধ্যে একটি। আমি সময়ে সময়ে এটি চালিয়েছি।
টর্স্টেন মেরেক

77
আমি যখন বুঝতে পেরেছি এটি বুঝতে অনেক সহজ পেলাম যে ডিফল্ট আর্গুমেন্টগুলি একটি টুপলে থাকে যা ফাংশনের একটি বৈশিষ্ট্য foo.func_defaults। যেটি একটি টিপল হয়ে উঠতে পারে তা পরিবর্তনযোগ্য able
রবার্ট রসনি

2
@ গ্রেগার: ডিএফ স্টেটমেন্ট কার্যকর হওয়ার সাথে সাথে তার যুক্তিগুলি দোভাষী দ্বারা মূল্যায়ন করা হয়। এটি একটি কোড অবজেক্টের (ফাংশনের স্যুট) একটি নাম তৈরি করে (বা পুনরায় ফিরিয়ে দেয়)। তবে সংজ্ঞার সময় ডিফল্ট আর্গুমেন্টগুলি অবজেক্ট হিসাবে ইনস্ট্যান্ট করা হয় ated এটি ডিফল্ট অবজেক্টের যে কোনও সময়ের ক্ষেত্রে সত্য, তবে কেবলমাত্র তাৎপর্যপূর্ণ (দৃশ্যমান শব্দার্থকতা প্রকাশ করা) যখন বস্তুটি পরিবর্তনযোগ্য হবে। ফাংশনটির বন্ধ হয়ে গেলে সেই ডিফল্ট আর্গুমেন্টের নামটি পুনরায় বাঁধনের কোনও উপায় নেই যদিও এটি কোনও কলের জন্য স্পষ্টতই অতিরিক্ত চালিত হতে পারে বা পুরো ফাংশনটিকে পুনরায় সংজ্ঞায়িত করা যেতে পারে)।
জিম ডেনিস

3
@ রবার্ট অবশ্যই টিপল আর্গুমেন্টগুলি অপরিবর্তনীয় হতে পারে তবে এটি যে বিষয়গুলিকে নির্দেশ করেছে তা অপরিবর্তনীয় নয়।
পুলি

16
আপনার সূচনাটি আরও ছোট করার জন্য একটি দ্রুত হ্যাক: x = x বা []। আপনি যদি স্টেটমেন্ট 2 লাইনের পরিবর্তে এটি ব্যবহার করতে পারেন।
ডেভ ম্যানকফ

317

জেনারেটর ফাংশনে মান পাঠানো হচ্ছে । উদাহরণস্বরূপ এই ফাংশনটি থাকার:

def mygen():
    """Yield 5 until something else is passed back via send()"""
    a = 5
    while True:
        f = (yield a) #yield a and possibly get f in return
        if f is not None: 
            a = f  #store the new value

আপনি পারেন:

>>> g = mygen()
>>> g.next()
5
>>> g.next()
5
>>> g.send(7)  #we send this back to the generator
7
>>> g.next() #now it will yield 7 until we send something else
7

একমত। আসুন একে পাইথনের লুকানো বৈশিষ্ট্যের একটি বাজে উদাহরণ হিসাবে ধরা যাক :)
রাফা ডগির্গ

89
অন্যান্য ভাষায়, আমি বিশ্বাস করি যে এই যাদুকরী ডিভাইসটিকে "ভেরিয়েবল" বলা হয়।
ফিনউইউ

5
কর্টাইনগুলি কর্টিনগুলি হওয়া উচিত এবং জেনারেটরটি নিজেও হওয়া উচিত, মেশানো ছাড়াই। মেগা-দুর্দান্ত লিঙ্ক এবং কথা এবং এখানে উদাহরণ সম্পর্কে: dabeaz.com/coroutines
u0b34a0f6ae

31
@ ফিনওয়ান: উদাহরণটি এমন কিছু প্রয়োগ করে যা ভেরিয়েবলের অনুরূপ। তবে বৈশিষ্ট্যটি অন্য অনেক উপায়ে ব্যবহার করা যেতে পারে ... ভেরিয়েবলের বিপরীতে। এটিও স্পষ্ট হওয়া উচিত যে একই ধরণের শব্দার্থক বস্তু ব্যবহার করে প্রয়োগ করা যেতে পারে ( বিশেষত বিশেষত পাইথনের কল পদ্ধতি প্রয়োগকারী একটি শ্রেণি )।
জিম ডেনিস

4
এটি এমন লোকদের পক্ষে খুব তুচ্ছ উদাহরণ যা কখনও সহ-রুটিনগুলি দেখেনি (এবং সম্ভবত বুঝতে পারে না)। যোগ ভেরিয়েবল ওভারফ্লোয়ের ঝুঁকি ছাড়াই চলমান গড়কে কার্যকর করা উদাহরণটি একটি ভাল।
প্রশান্ত কুমার

313

আপনি যদি স্কোপগুলি বোঝাতে হোয়াইটস্পেস ব্যবহার করতে পছন্দ করেন না তবে আপনি জারি করে সি-স্টাইল {use ব্যবহার করতে পারেন:

from __future__ import braces

122
এটা খারাপ। :)
জেসন বেকার

37
>>> ___ ভবিষ্যত__ থেকে আমদানি করা বন্ধনী ফাইল "<stdin>", লাইন 1 সিনট্যাক্স এরর: কোনও সুযোগ নেই: পি
ডব্লিউ স্মিথ

40
এটাই নিন্দা!
বার্ক ডি ডেমির

335
আমি মনে করি যে আমাদের এখানে একটি সিন্ট্যাক্টিকাল ভুল হতে পারে, এটি " __p_____ আমদানি বন্ধনীগুলি থেকে" হওয়া উচিত নয় ?
বিল কে

47
থেকে __cruft__ আমদানি ধনুর্বন্ধনী
ফিলিপ বি ওল্ডহাম

305

স্লাইস অপারেটরগুলিতে পদক্ষেপ যুক্তি। উদাহরণ স্বরূপ:

a = [1,2,3,4,5]
>>> a[::2]  # iterate over the whole list in 2-increments
[1,3,5]

বিশেষ ক্ষেত্রে x[::-1]হ'ল 'এক্স বিপরীত' এর জন্য একটি দরকারী আইডিয়াম।

>>> a[::-1]
[5,4,3,2,1]

31
আমার মতে অনেক পরিষ্কার, বিপরীত () ফাংশন। >>> তালিকা (বিপরীত (পরিসর (4))) [3, 2, 1, 0]
ক্রিশ্চিয়ান ওডার্ড

3
তাহলে কীভাবে "এই আইআ স্ট্রিং" [:: - 1] আরও ভাল উপায়ে লেখা যায়?
বিপরীতগুলি

24
বিপরীত () এর সমস্যাটি হ'ল এটি একটি পুনরাবৃত্তিকে ফেরত দেয়, তাই আপনি যদি বিপরীত ক্রমের ধরণটি (টিপল, স্ট্রিং, তালিকা, ইউনিকোড, ব্যবহারকারীর ...) সংরক্ষণ করতে চান তবে এটিকে আবার রূপান্তর করতে আপনার একটি অতিরিক্ত পদক্ষেপের প্রয়োজন you ।
রাফা ডগির্ড

6
ডিফ রিভার্স_স্ট্রিং (স্ট্রিং): রিটার্ন স্ট্রিং [:: - 1]
পাই।

4
@ পিআই, আমি মনে করি আপনার যদি বিপরীত স্ট্রিং সংজ্ঞায়িত করতে যদি কেউ যথেষ্ট পরিমাণে জানে তবে কেউ আপনার কোডটিতে [:: - 1] রেখে দিতে পারেন এবং এর অর্থ এবং এটি যথাযথ অনুভূতিতে স্বাচ্ছন্দ্য বোধ করতে পারেন।
পদার্থবিজ্ঞান

289

সজ্জা

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

উদাহরণ একটি print_argsসাজসজ্জা প্রদর্শন করে যা এটি কল করার আগে সজ্জিত ফাংশনটির যুক্তিগুলি মুদ্রণ করে:

>>> def print_args(function):
>>>     def wrapper(*args, **kwargs):
>>>         print 'Arguments:', args, kwargs
>>>         return function(*args, **kwargs)
>>>     return wrapper

>>> @print_args
>>> def write(text):
>>>     print text

>>> write('foo')
Arguments: ('foo',) {}
foo

54
সাজসজ্জার সংজ্ঞা দেওয়ার সময়, আমি ডেকোরেটর দিয়ে সাজসজ্জারকে সাজানোর পরামর্শ দেব। এটি একটি সাজসজ্জা তৈরি করে যা এতে অন্তর্নির্ধারণের সময় ফাংশনগুলির স্বাক্ষর সংরক্ষণ করে। এখানে আরও তথ্য: phyast.pitt.edu/~micheles/python/docamentation.html
sirwart

45
এটি কেমন লুকানো বৈশিষ্ট্য?
ভেটল

50
ঠিক আছে, এটি বেশিরভাগ সাধারণ পাইথন টিউটোরিয়ালে উপস্থিত নেই এবং পাইথনটি ব্যবহার শুরু করার পরে আমি দীর্ঘসময় এটিতে হোঁচট খেয়েছি। এটাই আমি একটি লুকানো বৈশিষ্ট্য বলব, এখানে অন্যান্য শীর্ষ পোস্টগুলির মতোই।
DzinX

16
প্রশ্ন, "পাইথন প্রোগ্রামিং ভাষার কম জ্ঞাত তবে দরকারী বৈশিষ্ট্যগুলির জন্য" জিজ্ঞাসা করে। আপনি 'কম-পরিচিত তবে দরকারী বৈশিষ্ট্যগুলি' কীভাবে পরিমাপ করবেন? মানে এই প্রতিক্রিয়াগুলির কোনও লুকানো বৈশিষ্ট্যগুলি কীভাবে রয়েছে?
জন

4
@ ওয়েলটার এখানে বেশিরভাগ জিনিস খুব কমই "লুকানো" থাকে।
হামফ্রে বোগার্ট

288

এর জন্য ... অন্য বাক্য গঠন (দেখুন http://docs.python.org/ref/for.html )

for i in foo:
    if i == 0:
        break
else:
    print("i was never 0")

"অন্য" ব্লকটি সাধারণত লুপের শেষে লুপের শেষে কার্যকর করা হবে, যদি না বিরতি বলা হয়।

উপরের কোডটি নিম্নরূপে অনুকরণ করা যেতে পারে:

found = False
for i in foo:
    if i == 0:
        found = True
        break
if not found: 
    print("i was never 0")

218
আমি মনে করি / অন্য বাক্য গঠনটি বিশ্রী। এটি "অনুভব করে" যেন লুপের বডিটি কখনই কার্যকর না করা হয় তবে অন্য ধারাটি কার্যকর করা উচিত।
কোডেপ

14
অই। ওকে দেখেনি! তবে আমি অবশ্যই বলব যে এটি কিছুটা মিসনোমার। বিরতি কখনই না ঘটলে কে অন্য ব্লকটি কার্যকর করতে পারে বলে আশা করবে? আমি কোডেপের সাথে একমত: মনে হচ্ছে খালি ফুসের জন্য অন্য কোনও প্রবেশ করা হয়েছে।
ড্যারেন টমাস

52
কীওয়ার্ডটি শেষ পর্যন্ত হওয়া উচিত বলে মনে হচ্ছে অন্যথায় নয়
জিয়াআরো

21
ইতিমধ্যে ইতিমধ্যে এমনভাবে ব্যবহার করা হয় যেখানে সেই স্যুটটি সর্বদা কার্যকর করা হয়।

7
অবশ্যই 'অন্য' না হওয়া উচিত। লুপ কখনই কার্যকর হয় নি তার জন্য সম্ভবত 'তখন' বা কিছু এবং তারপরে 'অন্য' '
টোর ভ্যালামো

258

2.5 থেকে ডিক্টসের কাছে একটি বিশেষ পদ্ধতি রয়েছে __missing__যা নিখোঁজ আইটেমগুলির জন্য অনুরোধ করা হয়:

>>> class MyDict(dict):
...  def __missing__(self, key):
...   self[key] = rv = []
...   return rv
... 
>>> m = MyDict()
>>> m["foo"].append(1)
>>> m["foo"].append(2)
>>> dict(m)
{'foo': [1, 2]}

ডিক্টে একটি ডিক সাবক্লাসও রয়েছে collectionsযা এতে defaultdictপ্রায় একই কাজ করে তবে বিদ্যমান আইটেমগুলির পক্ষে যুক্তি ছাড়াই একটি ফাংশনকে ডাকে:

>>> from collections import defaultdict
>>> m = defaultdict(list)
>>> m["foo"].append(1)
>>> m["foo"].append(2)
>>> dict(m)
{'foo': [1, 2]}

আমি এই জাতীয় ডিকটগুলিকে এমন ফাংশনগুলিতে পাস করার আগে এগুলিকে নিয়মিত ডিস্কে রূপান্তরিত করার পরামর্শ দিচ্ছি যা এ জাতীয় সাবক্লাসগুলি আশা করে না। প্রচুর কোড ব্যবহার করে d[a_key]এবং কীআরআরগুলি ক্যাচ করে কোনও আইটেম উপস্থিত রয়েছে যা ডিকটিতে একটি নতুন আইটেম যুক্ত করবে কিনা তা পরীক্ষা করতে।


10
আমি সেটডিফল্ট ব্যবহার পছন্দ করি। মি = {}; m.setdefault ('foo', 1)
গ্রেজার গ্রেড

22
@grayger মানে m={}; m.setdefault('foo', []).append(1)
ক্রিশ্চিয়ান সিউপিতু

1
তবে এমন কিছু ক্ষেত্রে রয়েছে যেখানে ডিফল্টডিক্টিক্টটি পাস করা খুব সহজ is ফাংশন উদাহরণস্বরূপ মানটির চেয়ে বেশি হতে পারে এবং এটি অতিরিক্ত কোড ছাড়াই অপরিজ্ঞাত কীগুলির জন্য কাজ করে, কারণ ডিফল্ট খালি তালিকা।
মারিয়ান

3
ডিফল্ট ডিটিক্ট কিছু পরিস্থিতিতে সেটডিফোল্টের চেয়ে ভাল, কারণ কীটি অনুপস্থিত না হলে এটি ডিফল্ট অবজেক্টটি তৈরি করে না । সেটডিফল্ট এটি নিখোঁজ হয়েছে কি নেই তা তৈরি করে। যদি আপনার ডিফল্ট অবজেক্টটি তৈরি করা ব্যয়বহুল হয় তবে এটি একটি পারফরম্যান্স হিট হতে পারে - আমি কেবলমাত্র সমস্ত সেটডিফল্ট কল পরিবর্তন করে একটি প্রোগ্রামের বাইরে একটি শালীন গতি অর্জন করি।
হোয়াটাং

2
defaultdictsetdefaultঅন্যান্য ক্ষেত্রে পদ্ধতির চেয়েও বেশি শক্তিশালী । উদাহরণস্বরূপ, একটি কাউন্টারের জন্য - dd = collections.defaultdict(int) ... dd[k] += 1বনাম d.setdefault(k, 0) += 1
মাইক গ্রাহাম

247

ইন-প্লেস মান অদলবদল

>>> a = 10
>>> b = 5
>>> a, b
(10, 5)

>>> a, b = b, a
>>> a, b
(5, 10)

অ্যাসাইনমেন্টের ডান হাতটি একটি অভিব্যক্তি যা একটি নতুন টিপল তৈরি করে। অ্যাসাইনমেন্টের বাম-হাত তত্ক্ষণাত আনপ্যাক করে যা নামগুলি (অবাস্তবহীন) টিপল করে aএবং b

অ্যাসাইনমেন্টের পরে, নতুন টিউপলটি অবাস্তব নয় এবং আবর্জনা সংগ্রহের জন্য চিহ্নিত করা হয়েছে aএবং মানগুলিতে আবদ্ধ হওয়া এবং bঅদলবদল করা হয়েছে।

ডেটা স্ট্রাকচারের পাইথন টিউটোরিয়াল বিভাগে যেমন উল্লেখ করা হয়েছে ,

নোট করুন যে একাধিক অ্যাসাইনমেন্ট আসলে টিউপল প্যাকিং এবং সিকোয়েন্স আনপ্যাকিংয়ের সংমিশ্রণ।


1
এটি কি traditionalতিহ্যবাহী পদ্ধতির চেয়ে আরও সত্যিকারের স্মৃতি ব্যবহার করে? আমি অনুমান করব যেহেতু আপনি কেবলমাত্র একটি স্ব্যাপ ভেরিয়েবলের পরিবর্তে একটি টুপল তৈরি করছেন
নাথান

75
এটি বেশি স্মৃতি ব্যবহার করে না। এটি কম ব্যবহার করে .. আমি এটি উভয় উপায়ে লিখেছি এবং বাইটকোডটি ডি-সংকলন করেছি .. সংকলকটি অনুকূলিত হয়েছে, যেমনটি আপনি আশা করেন যে এটি করবে। ডিসের ফলাফলগুলি দেখায় যে এটি ভার্স সেট আপ করছে এবং তারপরে ROT_TWOing। ROT_TWO এর অর্থ 'দুটি সর্বাধিক স্ট্যাক ভার্স অদলবদল করা ... ... সুন্দর চটুল, আসলে।
রাজকীয়

5
আপনি অজান্তে পাইথনের আরও একটি দুর্দান্ত বৈশিষ্ট্যও নির্দেশ করেছেন, এটি হ'ল আপনি স্পষ্টভাবে কমা দ্বারা পৃথক করে আইটেমগুলির একটি বড় আকার তৈরি করতে পারেন।
asmeurer

3
দানা দ্য সান: পাইথনে অ্যাসাইনমেন্টটি একটি বিবৃতি, কোনও অভিব্যক্তি নয়, সুতরাং = উচ্চতর অগ্রাধিকার থাকলে অভিব্যক্তিটি অবৈধ হবে (যেমন এটি একটি, (খ = খ), ক হিসাবে ব্যাখ্যা করা হয়েছিল)।
এইচবিএন

5
আমি এখানে পড়েছি এটি সর্বনিম্ন লুকানো বৈশিষ্ট্য। চমৎকার, তবে প্রতিটি পাইথন টিউটোরিয়ালে স্পষ্টভাবে বর্ণিত।
থিয়াগো

235

পাঠযোগ্য নিয়মিত প্রকাশ

পাইথনে আপনি একাধিক লাইনের উপর একটি নিয়মিত ভাব প্রকাশ করতে পারেন, আপনার মিলগুলির নাম দিন এবং মন্তব্যগুলি sertোকাতে পারেন।

ভার্জোজ সিনট্যাক্স উদাহরণ ( পাইথনে ডুব থেকে ):

>>> pattern = """
... ^                   # beginning of string
... M{0,4}              # thousands - 0 to 4 M's
... (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
...                     #            or 500-800 (D, followed by 0 to 3 C's)
... (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
...                     #        or 50-80 (L, followed by 0 to 3 X's)
... (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
...                     #        or 5-8 (V, followed by 0 to 3 I's)
... $                   # end of string
... """
>>> re.search(pattern, 'M', re.VERBOSE)

নামকরণের মিলগুলি উদাহরণ ( নিয়মিত এক্সপ্রেশন হাওটো থেকে )

>>> p = re.compile(r'(?P<word>\b\w+\b)')
>>> m = p.search( '(((( Lots of punctuation )))' )
>>> m.group('word')
'Lots'

আপনি re.VERBOSEআক্ষরিক যুক্তিযুক্ত স্ট্রিংকে ধন্যবাদ না দিয়ে মৌখিকভাবে একটি রেজেক্স লিখতে পারেন ।

>>> pattern = (
...     "^"                 # beginning of string
...     "M{0,4}"            # thousands - 0 to 4 M's
...     "(CM|CD|D?C{0,3})"  # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
...                         #            or 500-800 (D, followed by 0 to 3 C's)
...     "(XC|XL|L?X{0,3})"  # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
...                         #        or 50-80 (L, followed by 0 to 3 X's)
...     "(IX|IV|V?I{0,3})"  # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
...                         #        or 5-8 (V, followed by 0 to 3 I's)
...     "$"                 # end of string
... )
>>> print pattern
"^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$"

7
আমি জানি না যে আমি যদি সত্যিই এটি পাইথন বৈশিষ্ট্যটি বিবেচনা করি তবে বেশিরভাগ আরই ইঞ্জিনগুলির একটি ভার্বোস বিকল্প রয়েছে।
জেরেমি ব্যাংকগুলি

18
হ্যাঁ, তবে আপনি এটি গ্রেপ বা বেশিরভাগ সম্পাদকের মধ্যে করতে না পারার কারণে, অনেক লোক জানেন না যে সেখানে রয়েছে। অন্যান্য ভাষার সমতুল্য বৈশিষ্ট্য রয়েছে এটিকে অজগরটির দরকারী এবং অল্প পরিচিত বৈশিষ্ট্য হিসাবে তৈরি করে না
মার্ক বাকের

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

আমি বরং বলি: শত = "(সিএম | সিডি | ডি? সি {0,3})" # 900 (সিএম), 400 (সিডি), ইত্যাদি ভাষা ইতিমধ্যে জিনিসগুলির নাম দেওয়ার একটি উপায় রয়েছে, একটি মন্তব্য যুক্ত করার উপায় এবং স্ট্রিংগুলিকে একত্রিত করার উপায়। ভাষা ইতিমধ্যে পুরোপুরি ভাল করে এমন জিনিসগুলির জন্য কেন এখানে বিশেষ গ্রন্থাগার সিনট্যাক্স ব্যবহার করবেন? এটি সরাসরি পেরিলির 'এপিগ্রাম 9. এর বিপরীতে চলেছে বলে মনে হচ্ছে
কেনের

3
@ কেন: একটি রেজেক্স সর্বদা সরাসরি উত্সে নাও থাকতে পারে, সেটি সেটিংস বা কোনও কনফিগার ফাইল থেকে পড়তে পারে। মন্তব্য বা কেবল অতিরিক্ত শ্বেত স্পেসের (পাঠযোগ্যতার জন্য) মঞ্জুরি দেওয়া দুর্দান্ত সাহায্য হতে পারে।

222

ফাংশন যুক্তি আনপ্যাক করা king

আপনি একটি তালিকা বা অভিধান ব্যবহার করে ফাংশন আর্গুমেন্ট হিসাবে আনপ্যাক করতে পারেন * এবং**

উদাহরণ স্বরূপ:

def draw_point(x, y):
    # do some magic

point_foo = (3, 4)
point_bar = {'y': 3, 'x': 2}

draw_point(*point_foo)
draw_point(**point_bar)

তালিকা, টিপলস এবং ডিক্টগুলি পাত্রে হিসাবে ব্যাপকভাবে ব্যবহৃত হয় বলে খুব দরকারী শর্টকাট।


27
* স্প্ল্যাট অপারেটর হিসাবেও পরিচিত
গ্যাব্রিয়েল

3
আমি এই বৈশিষ্ট্যটি পছন্দ করি তবে পাইলট দুঃখজনকভাবে লাগে না।
স্টিফেন পলগার

5
পাইলট পরামর্শ একটি আইন নয়। অন্য উপায়ে, প্রয়োগ করুন (কলযোগ্য, আরগ_সেক, আরজি_ম্যাপ), ২.৩ থেকে অবহেলিত।
ইয়ান ভার্নিয়ার

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

2
আমি এটি কোডে একবার ব্যবহার হতে দেখলাম এবং ভাবলাম কী করেছে এটি। দুর্ভাগ্যক্রমে "পাইথন **"
ফ্রেজার গ্রাহাম

205

ROT13 হল উত্স কোডের জন্য একটি বৈধ এনকোডিং, যখন আপনি কোড ফাইলের শীর্ষে ডান কোডিং ঘোষণাটি ব্যবহার করেন:

#!/usr/bin/env python
# -*- coding: rot13 -*-

cevag "Uryyb fgnpxbiresybj!".rapbqr("rot13")

10
গ্রেট! আক্ষরিক অর্থে কীভাবে বাইট স্ট্রিং নেওয়া হয় তা লক্ষ্য করুন, তবে ইউনিকোড স্ট্রিংগুলি ডিকোড করা হয়েছে: চেষ্টা করুনcevag h"Uryyb fgnpxbiresybj!"
u0b34a0f6ae

12
দুর্ভাগ্যক্রমে এটি পাই 3 কে
মাইখাল

9
এটি অ্যান্টিভাইরাসকে বাইপাস করার জন্য ভাল।
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

96
এনকোডিংয়ের সাথে এর কোনও যোগসূত্র নেই, এটি কেবল ওয়েলশ ভাষায় লেখা পাইথন। :
অলিভিয়ার ভারদিয়ার

33
ফাংলুই মিলিগ্রাম'আনাফ চথুলহু রুলিহ ওয়াগাহ'নাগল ফিটাগন!
ম্যানুয়েল ফেরেরিয়া

183

সম্পূর্ণ গতিশীল পদ্ধতিতে নতুন ধরণের তৈরি করা

>>> NewType = type("NewType", (object,), {"x": "hello"})
>>> n = NewType()
>>> n.x
"hello"

যা ঠিক তেমনই

>>> class NewType(object):
>>>     x = "hello"
>>> n = NewType()
>>> n.x
"hello"

সম্ভবত সবচেয়ে দরকারী জিনিস না, তবে জেনে ভাল লাগছে।

সম্পাদনা : নতুন ধরণের স্থির নাম, বিবৃতি NewTypeসহ ঠিক একই জিনিস হওয়া উচিত class

সম্পাদনা করুন : বৈশিষ্ট্যটি আরও সঠিকভাবে বর্ণনা করতে শিরোনাম সামঞ্জস্য করেছেন।


8
এটিতে দরকারীতার অনেক সম্ভাবনা রয়েছে, যেমন, জেআইটি ওআরএম
মার্ক সিডেড

8
আমি এটি একটি গতিশীল ইনপুট এর উপর ভিত্তি করে এইচটিএমএল-ফর্ম ক্লাস উত্পন্ন করতে ব্যবহার করি। খুব সুন্দর!
পাই

15
দ্রষ্টব্য: সমস্ত ক্লাস রানটাইমে তৈরি করা হয়। সুতরাং আপনি শর্তসাপেক্ষে বা কোনও ফাংশনের মধ্যে 'ক্লাস' বিবৃতিটি ব্যবহার করতে পারেন (ক্লোজার বা ক্লাসের পরিবার তৈরির জন্য খুব দরকারী যা ক্লোজার হিসাবে কাজ করে)। 'টাইপ' যে উন্নতি নিয়ে আসে তা হ'ল গুনগতভাবে উত্পন্ন বৈশিষ্ট্যের সেটগুলি (বা বেসগুলি) পরিষ্কারভাবে সংজ্ঞায়িত করার ক্ষমতা।
spookylukey

1
আপনি একটি ফাঁকা স্ট্রিংয়ের সাথে বেনামে
টাইপগুলিও

3
কোড ইঞ্জেকশনগুলির জন্য খুব দরকারী হতে পারে।
অভিহু টার্জিওন

179

প্রসঙ্গ পরিচালক এবং " with" বিবৃতি

পিইপি 343 তে পরিচয় করিয়ে দেওয়া , একটি কনটেক্সট ম্যানেজার এমন একটি বস্তু যা বিবৃতিগুলির স্যুটটির জন্য রান-টাইম প্রসঙ্গ হিসাবে কাজ করে।

বৈশিষ্ট্যটি যেহেতু নতুন কীওয়ার্ড ব্যবহার করে, তাই এটি ধীরে ধীরে প্রবর্তিত হয়: এটি __future__নির্দেশের মাধ্যমে পাইথন 2.5 তে উপলব্ধ । পাইথন ২.6 এবং ততোধিক (পাইথন 3 সহ) এটি ডিফল্টরূপে উপলব্ধ।

আমি "উইথ" স্টেটমেন্টটি অনেক ব্যবহার করেছি কারণ আমি মনে করি এটি একটি খুব দরকারী নির্মাণ, এখানে একটি দ্রুত ডেমো রয়েছে:

from __future__ import with_statement

with open('foo.txt', 'w') as f:
    f.write('hello!')

পর্দার আড়ালে এখানে যা ঘটছে, তা হল "উইথ" স্টেটমেন্টটি ফাইল অবজেক্টের বিশেষ __enter__এবং __exit__পদ্ধতিগুলি কল করে । ব্যতিক্রমের বিবরণও পাস করা হয়েছে__exit__স্টেটমেন্ট বডি থেকে কোনও ব্যতিক্রম উত্থাপিত হলে , সেখানে ব্যতিক্রম হ্যান্ডলিংয়ের অনুমতি দেওয়া হয়েছে।

এই বিশেষ ক্ষেত্রে এটি আপনার জন্য যা করে তা হ'ল গ্যারান্টিটি দেয় যে মৃত্যুদণ্ড কার্যকর হওয়ার পরে withস্যুটটির স্কোপ থেকে সরে গেলে ফাইলটি বন্ধ হয়ে যায় , যদি তা সাধারণত ঘটে থাকে বা ব্যতিক্রম ছুঁড়েছিল কিনা তা নির্বিশেষে। এটি মূলত সাধারণ ব্যতিক্রম-হ্যান্ডলিং কোডটিকে বিমূর্ত করার উপায় is

এর জন্য অন্যান্য সাধারণ ব্যবহারের ক্ষেত্রে থ্রেড এবং ডাটাবেস লেনদেনের সাথে লক করা অন্তর্ভুক্ত।


3
আমি এমন কোনও কোড পর্যালোচনা অনুমোদন করব না যা ভবিষ্যতে কিছু আমদানি করে । বৈশিষ্ট্যগুলি দরকারীগুলির চেয়ে আরও সুন্দর এবং সাধারণত এগুলি পাইথন আগতদেরকে বিভ্রান্ত করে।
একটি বেতনের অস্থির

6
হ্যাঁ, নেস্টেড স্কোপস এবং জেনারেটরের মতো এই "সুন্দর" বৈশিষ্ট্যগুলি যারা জানেন তারা কী করছেন better এবং যে কেউ পাইথনের ভবিষ্যতের সংস্করণের সাথে সামঞ্জস্য করতে চায়। নেস্টেড স্কোপ এবং জেনারেটরের জন্য পাইথনের "ভবিষ্যতের সংস্করণগুলি" অর্থ যথাক্রমে ২.২ এবং 2.5 হয়। বিবৃতি সহ, পাইথনের "ভবিষ্যতের সংস্করণগুলি" অর্থ 2.6।
ক্রিস বি

10
এটি না বলে যেতে পারে তবে অজগর v2.6 + এর সাথে আপনাকে ভবিষ্যতে আর আমদানি করতে হবে না । সাথে এখন প্রথম শ্রেণীর কীওয়ার্ড।
ফিটজগেরাল্ডস্টিল

25
২.7-তে আপনি একাধিক থাকতে পারেন withs:) with open('filea') as filea and open('fileb') as fileb: ...
অস্টিন রিচার্ডসন

5
@ অস্টিন আমি এই সিনট্যাক্সটি 2.7-তে কাজ করতে পারি না। এই তবে করেনি কাজ: with open('filea') as filea, open('fileb') as fileb: ...
Wim

168

অভিধানের একটি গেট () পদ্ধতি রয়েছে

অভিধানের একটি 'গেট ()' পদ্ধতি রয়েছে। আপনি যদি ডি ['কী'] করেন এবং কীটি না থাকে তবে আপনি একটি ব্যতিক্রম পান। আপনি যদি d.get ('কী') করেন তবে 'কী' না থাকলে আপনি কোনওটিই ফিরে পাবেন না। আপনি এই আইটেমটি কারোর পরিবর্তে ফিরে পেতে দ্বিতীয় যুক্তি যুক্ত করতে পারেন, যেমন: d.get ('কী', 0)।

সংখ্যা যুক্ত করার মতো জিনিসগুলির জন্য এটি দুর্দান্ত:

sum[value] = sum.get(value, 0) + 1


39
এছাড়াও, সেটডেফল্ট পদ্ধতিটি চেকআউট করুন।
ড্যারেন টমাস

27
এছাড়াও, চেকআউট সংগ্রহ। ডিফল্টডিক্ট ক্লাস।
jfs

8
যদি আপনি পাইথন ২.7 বা তার বেশি বা তার পরে ৩.১ বা তার পরে ব্যবহার করেন তবে সংগ্রহের মডিউলটিতে কাউন্টার ক্লাসটি পরীক্ষা করে দেখুন। docs.python.org/library/collections.html#collections.Cauter
এলিয়াস জামারিয়া

ওহ, এই পুরো সময়টি আমি করছি get(key, None)Noneডিফল্টরূপে সরবরাহ করা হয়েছিল এমন কোনও ধারণা ছিল না ।
জর্ডান রিটার

152

বর্ণনাকারী

এগুলি পুরো পাইথন বৈশিষ্ট্যগুলির পুরো গুচ্ছটির পিছনে যাদু।

যখন আপনি কোনও সদস্যকে অনুসন্ধান করার জন্য বিন্দুযুক্ত অ্যাক্সেস ব্যবহার করেন (যেমন, এক্সওয়াই), পাইথন প্রথমে উদাহরণের অভিধানে সদস্যটির সন্ধান করে। এটি যদি খুঁজে পাওয়া যায় না, এটি শ্রেণীর অভিধানে এটি সন্ধান করে। এটি যদি শ্রেণি অভিধানে এটি খুঁজে পায় এবং অবজেক্টটি কেবল এটি ফিরিয়ে দেওয়ার পরিবর্তে ডেস্ক্রিপ্টর প্রোটোকল প্রয়োগ করে, পাইথন এটি কার্যকর করে। একজন বর্ণনাকারী কোন শ্রেণীর যে প্রয়োগ হয় __get__, __set__অথবা __delete__পদ্ধতি।

বর্ণনাকারী ব্যবহার করে আপনি কীভাবে নিজের সম্পত্তি (কেবল পঠনযোগ্য) সংস্করণটি প্রয়োগ করবেন তা এখানে রয়েছে:

class Property(object):
    def __init__(self, fget):
        self.fget = fget

    def __get__(self, obj, type):
        if obj is None:
            return self
        return self.fget(obj)

এবং আপনি এটি বিল্ট-ইন প্রোপার্টি () এর মতোই ব্যবহার করবেন:

class MyClass(object):
    @Property
    def foo(self):
        return "Foo!"

পাইথনে বর্ণনাকারী ব্যবহৃত হয় অন্যান্য জিনিসগুলির মধ্যে বৈশিষ্ট্য, আবদ্ধ পদ্ধতি, স্ট্যাটিক পদ্ধতি, শ্রেণিক পদ্ধতি এবং স্লটগুলি প্রয়োগ করতে। এগুলি বোঝার ফলে এটি দেখতে সহজ হয় যে আগে পাইথন 'কিরকস' এর মতো দেখতে অনেকগুলি জিনিস কেন সেভাবে হয়।

রেমন্ড হেটেঙ্গারের একটি দুর্দান্ত টিউটোরিয়াল রয়েছে যা তাদের চেয়ে বর্ণনা করার চেয়ে আরও ভাল কাজ করে।


এটি সাজসজ্জারের সদৃশ, তাই না !? ( Stackoverflow.com/questions/101268/... )
gecco

2
না, সাজসজ্জার এবং বর্ণনাকারী সম্পূর্ণ আলাদা জিনিস, যদিও উদাহরণ কোডে, আমি একটি বিবরণকারী সজ্জা তৈরি করছি। :)
নিক জনসন

1
এটি করার অন্য উপায়টি হ'ল ল্যাম্বদা সহ:foo = property(lambda self: self.__foo)
পিট পিটারসন

1
@ পেটপিটারসন হ্যাঁ, তবে propertyএটি বর্ণনাকারীদের দ্বারা প্রয়োগ করা হয়েছে, যা আমার পোস্টের মূল বিষয় ছিল।
নিক জনসন

142

শর্তসাপেক্ষ নিয়োগ

x = 3 if (y == 1) else 2

এটি ঠিক যা মনে হচ্ছে ঠিক তা করে: "y 1 হলে 3 থেকে x নির্ধারণ করুন, অন্যথায় 2 থেকে x নির্ধারণ করুন"। মনে রাখবেন যে পেরেনগুলি প্রয়োজনীয় নয়, তবে আমি তাদের পাঠযোগ্যতার জন্য পছন্দ করি। আপনার আরও জটিল কিছু হলে আপনি এটি চেইনও করতে পারেন:

x = 3 if (y == 1) else 2 if (y == -1) else 1

যদিও একটি নির্দিষ্ট সময়ে, এটি খানিকটা দূরে চলে যায়।

নোট করুন আপনি যদি অন্য কোনও অভিব্যক্তিতে ব্যবহার করতে পারেন তবে। উদাহরণ স্বরূপ:

(func1 if y == 1 else func2)(arg1, arg2) 

অন্যথায় অন্যথায়, এখানে y এবং 1 এবং func2 হলে ফানক 1 কল করা হবে। উভয় ক্ষেত্রে সংশ্লিষ্ট ফাংশনটি আর্গুমেন্ট আরজি 1 এবং আরজি 2 দিয়ে ডাকা হবে।

আনুষাঙ্গিকভাবে, নিম্নলিখিতগুলিও বৈধ:

x = (class1 if y == 1 else class2)(arg1, arg2)

যেখানে ক্লাস 1 এবং ক্লাস 2 দুটি ক্লাস।


29
অ্যাসাইনমেন্টটি বিশেষ অংশ নয়। আপনি ঠিক তেমন সহজেই কিছু করতে পারেন: 3 আবার (যদি y == 1) অন্য 2 করুন
ব্রায়ান

25
সেই বিকল্প উপায়টি আমি প্রথম বার পাইথনকে অবহেলা করে দেখেছি।
ক্রেগ ম্যাককুইন

3
কাইলব্রুকস: এটি সে ক্ষেত্রে নয়, বুলিয়ান অপারেটরদের শর্ট সার্কিট। এটি কেবল বুল (3) == মিথ্যা হলে 2 এর মূল্যায়ন করবে।
রোডিরিচ

15
এই পিছনের স্টাইল কোডিং আমাকে বিভ্রান্ত। এর মতো কিছু x = ((y == 1) ? 3 : 2)আমার কাছে আরও
অর্থবোধ করে

13
আমি @ মার্কের ঠিক বিপরীত বোধ করি, সি স্টাইলের টর্নারি অপারেটররা আমাকে সর্বদা বিভ্রান্ত করে রেখেছিল, ডান দিকটি বা মাঝখানে কি কোনও মিথ্যা শর্তে মূল্যায়ন হয়? আমি পাইথনের টার্নারি সিনট্যাক্সকে অনেক বেশি পছন্দ করি।
জেফ্রি হ্যারিস

141

ডক্টেস্ট : একই সাথে ডকুমেন্টেশন এবং ইউনিট-টেস্টিং।

পাইথন ডকুমেন্টেশন থেকে প্রাপ্ত উদাহরণ:

def factorial(n):
    """Return the factorial of n, an exact integer >= 0.

    If the result is small enough to fit in an int, return an int.
    Else return a long.

    >>> [factorial(n) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> factorial(-1)
    Traceback (most recent call last):
        ...
    ValueError: n must be >= 0

    Factorials of floats are OK, but the float must be an exact integer:
    """

    import math
    if not n >= 0:
        raise ValueError("n must be >= 0")
    if math.floor(n) != n:
        raise ValueError("n must be exact integer")
    if n+1 == n:  # catch a value like 1e300
        raise OverflowError("n too large")
    result = 1
    factor = 2
    while factor <= n:
        result *= factor
        factor += 1
    return result

def _test():
    import doctest
    doctest.testmod()    

if __name__ == "__main__":
    _test()

6
দস্তাবেজগুলি অবশ্যই দুর্দান্ত, তবে কোনও ব্যতিক্রম বাড়াতে হবে তা পরীক্ষা করতে আপনার টাইপ করতে হবে এমন সমস্ত ক্রুফটি আমি সত্যিই অপছন্দ করি
টিএম।

60
দস্তাবেজগুলি ওভাররেটেড হয় এবং ডকুমেন্টেশনকে দূষিত করে। আপনি কোনও সেটআপ () ছাড়াই কতক্ষণ স্ট্যান্ডেলোন ফাংশনটি পরীক্ষা করেন?
একটি অর্থ প্রদান

2
কে বলে যে আপনি ডক্টেস্টে সেটআপ করতে পারবেন না? একটি ফাংশন লিখুন যা প্রসঙ্গ উত্পন্ন করে এবং locals()তারপরে আপনার ডাক্তারে do locals().update(setUp())= D
জিয়াআরো

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

4
"আপনি কতবার স্ট্যান্ড্যালোন ফাংশনটি পরীক্ষা করেন" - প্রচুর। আমি ফ্যাসেডগুলি সিদ্ধান্ত নেওয়ার সময় নথিগুলি প্রায়শই নকশা প্রক্রিয়া থেকে প্রাকৃতিকভাবে উত্থিত দেখতে পাই।
গ্রেগ লিন্ড

138

নামকরণ বিন্যাস

%-ফর্ম্যাটিংয়ে একটি অভিধান লাগে (% i /% s ইত্যাদি বৈধতাও প্রযোজ্য)।

>>> print "The %(foo)s is %(bar)i." % {'foo': 'answer', 'bar':42}
The answer is 42.

>>> foo, bar = 'question', 123

>>> print "The %(foo)s is %(bar)i." % locals()
The question is 123.

এবং যেহেতু স্থানীয় () অভিধানও একটি অভিধান, আপনি কেবল এটি ডিক হিসাবে পাস করতে পারেন এবং আপনার স্থানীয় ভেরিয়েবলগুলি থেকে% -Substitions পেতে পারেন। আমি মনে করি এটি এটিকে অবহেলা করা হয়েছে, তবে জিনিসগুলি সরল করে তুলেছে ...

নতুন স্টাইল বিন্যাস

>>> print("The {foo} is {bar}".format(foo='answer', bar=42))

60
পর্যায়ক্রমে আউট হবে এবং শেষ পর্যন্ত স্ট্রিংয়ের ফর্ম্যাট () পদ্ধতিতে প্রতিস্থাপন করা হবে।
কনস্টান্টিন

3
নামকরণযুক্ত ফর্ম্যাটিং অনুবাদকদের পক্ষে খুব দরকারী কারণ তারা প্রসঙ্গের জন্য পরিবর্তনশীল নাম ছাড়াই বিন্যাসের স্ট্রিং দেখতে ঝোঁক
পিক্সেলবিট

2
পাইথন 3.0.০.১ এ কাজ করার জন্য প্রদর্শিত হয় (প্রিন্ট কলের চারপাশে প্যারেন্টেসিস যুক্ত করা দরকার)।
প্যাসি সাভোলাইনেন

9
একটি হ্যাশ , হাহ? আমি দেখছি তুমি কোথা থেকে এসেছ?
শাইলেন্ট

11
% s ফর্ম্যাটিংটি পর্যায়ক্রমে আসবে না। str.format () অবশ্যই আরও অজগর, তবে সাধারণ স্ট্রিং প্রতিস্থাপনের জন্য এটি আসলে 10x এর ধীর er আমার বিশ্বাস% s ফর্ম্যাট করা এখনও সেরা অনুশীলন।
কেনেথ রেইটস

132

আরও পাইথন মডিউল যুক্ত করার জন্য (বিশেষত তৃতীয় পক্ষের লোকেরা) বেশিরভাগ লোকেরা পাইথনপ্যাথ এনভায়রনমেন্ট ভেরিয়েবল ব্যবহার করেন বা তারা তাদের সাইট-প্যাকেজ ডিরেক্টরিতে সিমলিংক বা ডিরেক্টরি যুক্ত করেন। অন্য উপায়, * .pth ফাইল ব্যবহার করা হয়। অজগর ডকের সরকারী ব্যাখ্যা এখানে:

"সর্বাধিক সুবিধাজনক উপায় [পাইথনের অনুসন্ধানের পথটি পরিবর্তন করার জন্য] হ'ল পাইথনের পথে যে ডিরেক্টরিটি ইতিমধ্যে সাধারণত ... / সাইট-প্যাকেজ / ডিরেক্টরিতে যোগ করা হয় সেখানে একটি পাথ কনফিগারেশন ফাইল যুক্ত করা হয় Path , এবং প্রতিটি লাইনে অবশ্যই একটি একক পথ থাকা আবশ্যক যা sys.path এ সংযুক্ত করা হবে ((কারণ নতুন পথগুলি sys.path এ সংযুক্ত করা হয়েছে, যুক্ত ডিরেক্টরিগুলির মডিউলগুলি স্ট্যান্ডার্ড মডিউলগুলিকে ওভাররাইড করবে না This এর অর্থ আপনি এই পদ্ধতিটি ব্যবহার করতে পারবেন না মানক মডিউলগুলির স্থির সংস্করণ ইনস্টল করার জন্য) ")


1
আমি সেটআপলগুলি এবং এই ধারণা থেকে সাইট-প্যাকেজ ডিরেক্টরিতে .pth ফাইলের মধ্যে কখনও সংযোগ তৈরি করিনি। অসাধারণ.
ডেভ পাওলা

122

অন্য ধারা ব্যতিক্রম :

try:
  put_4000000000_volts_through_it(parrot)
except Voom:
  print "'E's pining!"
else:
  print "This parrot is no more!"
finally:
  end_sketch()

অন্য ধারাটির ব্যবহার ট্রাই ক্লজে অতিরিক্ত কোড যুক্ত করার চেয়ে ভাল কারণ এটি ঘটনাক্রমে এমন একটি ব্যতিক্রম ধরা এড়ায় যা কোড দ্বারা সুরক্ষিত করা না হয়ে চেষ্টা করা হয়েছিল ... বিবৃতি ব্যতীত।

Http://docs.python.org/tut/node10.html দেখুন


8
+1 এটি দুর্দান্ত। যদি চেষ্টা ব্লক কোনও ব্যতিক্রম ব্লক প্রবেশ না করেই কার্যকর করে, তবে অন্য ব্লকটি প্রবেশ করা হয়। এবং অবশ্যই, অবশেষে ব্লকটি কার্যকর করা হবে
ইন্সপেক্টর

অবশেষে আমি পেয়েছি কেন 'অন্য' আছে! ধন্যবাদ।
taynaron

এটি চালিয়ে যাওয়া আরও বোধগম্য হবে, তবে আমার ধারণা এটি ইতিমধ্যে নেওয়া হয়েছে;)
পাওয়ে প্র্যাক

দ্রষ্টব্য যে পাইথন 2 এর পুরানো সংস্করণগুলিতে আপনার আর দুটি থাকতে পারে না: এবং শেষ অবধি: একই চেষ্টা করার জন্য ধারা: ব্লক
কেভিন হর্ন

1
@ পাউয়ে প্রেরাক, যেমন কেভিন হর্ন উল্লেখ করেছেন, পাইথনের প্রাথমিক প্রকাশের পরে এই বাক্য গঠনটি চালু করা হয়েছিল এবং বিদ্যমান ভাষায় নতুন সংরক্ষিত কীওয়ার্ড যুক্ত করা সবসময় সমস্যাযুক্ত। এজন্য একটি বিদ্যমান কীওয়ার্ডটি সাধারণত পুনরায় ব্যবহৃত হয় (সাম্প্রতিক সি ++ স্ট্যান্ডার্ডে সিএফ "অটো")।
কনস্টান্টিন

114

পুনরায় উত্থাপন ব্যতিক্রমগুলি :

# Python 2 syntax
try:
    some_operation()
except SomeError, e:
    if is_fatal(e):
        raise
    handle_nonfatal(e)

# Python 3 syntax
try:
    some_operation()
except SomeError as e:
    if is_fatal(e):
        raise
    handle_nonfatal(e)

কোনও ত্রুটি হ্যান্ডলারের ভিতরে কোনও যুক্তি ছাড়াই 'উত্থাপন' বিবৃতি পাইথনকে মূল ট্রেসব্যাক অক্ষত রেখে পুনরায় ব্যতিক্রমটি উত্থাপন করতে বলে, "ওহ, দুঃখিত, দুঃখিত, আমি এটি ধরতে চাইছিলাম না, দুঃখিত, দুঃখিত। "

আপনি যদি মূল ট্রেসব্যাকের সাহায্যে মুদ্রণ, সঞ্চয় বা ফিডল করতে চান তবে আপনি এটি sys.exc_info () দিয়ে পেতে পারেন এবং পাইথনের মতো এটি মুদ্রণ 'ট্রেসব্যাক' মডিউল দিয়ে সম্পন্ন করা হবে।


দুঃখিত তবে এটি প্রায় সমস্ত ভাষার একটি সুপরিচিত এবং সাধারণ বৈশিষ্ট্য।
লুকাস এস।

6
Italicized পাঠ্য নোট করুন। কিছু লোক raise eপরিবর্তে এটি করবে , যা মূল ট্রেসব্যাক সংরক্ষণ করে না।
হাবনবিত

12
সম্ভবত আরও যাদুকরী, এটির exc_info = sys.exc_info(); raise exc_info[0], exc_info[1], exc_info[2]সমতুল্য, তবে আপনি সেই মানগুলি চারপাশে পরিবর্তন করতে পারেন (যেমন, ব্যতিক্রমের প্রকার বা বার্তা পরিবর্তন করুন)
আইয়ানব

3
@ লুকাস এস ভাল, আমি এটি জানতাম না এবং আমি আনন্দিত যে এটি এখানে লেখা আছে।
ই-সন্তুষ্ট

আমি এখানে আমার যৌবনে প্রদর্শিত হতে পারি তবে আমি অজগর ২.7 তে সর্বদা অজগর 3 সিনট্যাক্সটি ব্যবহার করেছি কোনও সমস্যা ছাড়াই
উইম

106

প্রধান বার্তা :)

import this
# btw look at this module's source :)

ডি-সাইফার্ড :

টিম পিটার্স দ্বারা নির্মিত পাইথনের জেন

কদর্য চেয়ে সুন্দর।
সুস্পষ্ট বর্ণিত চেয়ে ভাল।
সহজ জটিল চেয়ে ভাল।
জটিল জটিল চেয়ে ভাল।
নেস্টেড থেকে ফ্ল্যাট ভাল।
গা Sp়ের চেয়ে বিরাগই ভাল।
পঠনযোগ্যতা গণনা।
বিশেষ কেসগুলি নিয়ম ভাঙার পক্ষে যথেষ্ট বিশেষ নয়। যদি বাস্তবায়নটি ব্যাখ্যা করা শক্ত হয় তবে এটি একটি খারাপ ধারণা। বাস্তবায়নটি যদি ব্যাখ্যা করা সহজ হয় তবে এটি একটি ভাল ধারণা হতে পারে। নেমস্পেসগুলি হ'ল একটি দুর্দান্ত ধারণা - আসুন আমরা তাদের আরও কিছু করি!
যদিও ব্যবহারিকতা বিশুদ্ধতা বীট।
ত্রুটিগুলি কখনই নিঃশব্দে কাটানো উচিত নয়।
স্পষ্টভাবে নিরব না হলে।
অস্পষ্টতার মুখে অনুমান করার প্রলোভনটিকে অস্বীকার করুন। এটির জন্য একটি - এবং অগ্রাধিকার কেবল একটিই - প্রকাশ্য উপায় থাকতে হবে।
যদিও আপনি ডাচ না হলে এই উপায়টি প্রথমে সুস্পষ্ট নাও হতে পারে।
এখন আগের চেয়ে ভাল is
যদিও কখনও কখনও এর চেয়ে ভাল হয় নাঅধিকার এখন।



1
কোনও ধারণা কেন উত্সটি সেভাবে ছড়িয়ে দেওয়া হয়েছিল? এটি কি কেবল মজাদার জন্যই ছিল, না অন্য কোনও কারণ ছিল?
MiniQuark

42
উত্সটি যেভাবে লেখা হয়েছে তা জেনের বিপরীতে যায়!
হাসেন


2
আমি আমার /usr/lib/python2.6/this.py আপডেট করেছি print s.translate("".join(chr(64<i<91 and 65+(i-52)%26 or 96<i<123 and 97+(i-84)%26 or i) for i in range(256)))এবং এটি দিয়ে পুরানো কোডটি প্রতিস্থাপন করেছি এবং এটি এখন আরও ভাল দেখাচ্ছে! :-D
ফরটারন

2
@ মিনিকিয়ার্ক: দ্রুত ইতিহাস পাঠ: wefearchange.org/2010/06/import-this-

105

ইন্টারেক্টিভ ইন্টারপ্রেটার ট্যাব সমাপ্তি

try:
    import readline
except ImportError:
    print "Unable to load readline module."
else:
    import rlcompleter
    readline.parse_and_bind("tab: complete")


>>> class myclass:
...    def function(self):
...       print "my function"
... 
>>> class_instance = myclass()
>>> class_instance.<TAB>
class_instance.__class__   class_instance.__module__
class_instance.__doc__     class_instance.function
>>> class_instance.f<TAB>unction()

আপনাকে একটি পাইথনস্টার্টআপ পরিবেশ পরিবর্তনশীলও সেট করতে হবে।


2
এটি একটি খুব দরকারী বৈশিষ্ট্য। এটিকে সক্ষম করার জন্য আমি এত সহজ সরল স্ক্রিপ্ট পেয়েছি (আরও কয়েকটি অন্তর্নির্ধারণের বর্ধিততা
স্ক্রিপ্টস

43
আইপিথন আপনাকে এই আরও প্লাস টন অন্যান্য ঝরঝরে স্টাফ দেয়
আকাইহোলা

এটি পিডিবি প্রম্পটে নিয়মিত পাইথন প্রম্পটের চেয়ে আরও কার্যকর হতে পারে (আইপিথন যেভাবেই সেই উদ্দেশ্যে কাজ করে)। তবে, এটি পিডিবি প্রম্পটে কাজ করবে বলে মনে হচ্ছে না, সম্ভবত কারণ পিডিবি তার নিজস্ব ট্যাবটির জন্য আবদ্ধ করে (যা কম কার্যকর)। আমি pdb প্রম্পটে parse_and_bind () কল করার চেষ্টা করেছি, কিন্তু এটি এখনও কার্যকর হয়নি। আইপিথনের সাথে পিডিবি প্রম্পট পাওয়ার বিকল্পটি আরও কাজ, সুতরাং আমি এটি ব্যবহার না করার ঝোঁক।
haridsv

2
@haridsv - easy_install ipdb- তারপরে আপনি ব্যবহার করতে পারেনimport ipdb; ipdb.set_trace()
ডগ হ্যারিস

1
অসক্সে [এবং আমি অন্যান্য সিস্টেমগুলি যা লিবিডিট ব্যবহার করে তা কল্পনা করে] আপনাকে করতে হবেreadline.parse_and_bind ("bind ^I rl_complete")
ফু বাহ

91

নেস্টেড তালিকা বোঝার এবং জেনারেটর এক্সপ্রেশন:

[(i,j) for i in range(3) for j in range(i) ]    
((i,j) for i in range(4) for j in range(i) )

এগুলি নেস্টেড-লুপ কোডের বিশাল অংশগুলি প্রতিস্থাপন করতে পারে।


"জে রেঞ্জের জন্য (i)" - এটি কি টাইপো? সাধারণত আপনি i এবং j এর জন্য নির্দিষ্ট রেঞ্জ চান। আপনি যদি 2 ডি অ্যারে অ্যাক্সেস করে থাকেন তবে আপনি নিজের অর্ধেক উপাদানকে হাতছাড়া করবেন।
পিটার গিবসন

আমি এই উদাহরণে কোনও অ্যারে অ্যাক্সেস করছি না। এই কোডের একমাত্র উদ্দেশ্যটি দেখানো হয় যে অভ্যন্তরীণ রেঞ্জের প্রকাশগুলি বাইরের দিক থেকে আসাগুলিকে অ্যাক্সেস করতে পারে। উপ-পণ্যটি জোড়গুলির (x, y) এর তালিকা যা 4> x> y> 0।
রাফা ডগার্ড

2
ক্যালকুলাসে ডাবল ইন্টিগ্রেশন বা ডাবল সারসংক্ষেপের মতো বাছাই।
ইউ

22
এখানে মনে রাখার মূল বিষয়টি (যা আমাকে বুঝতে দীর্ঘ সময় নিয়েছিল) হ'ল যে forবিবৃতিগুলির ক্রমটি সেই ক্রমে লিখতে হবে যা আপনি প্রত্যাশা করছিলেন যে সেগুলি বাইরের দিকের দিক থেকে একটি স্ট্যান্ডার্ড লুপে লেখা হবে।
সিকোড়া

2
Sykora এর মন্তব্যের যোগ করার জন্য: মনে করুন আপনার একটি স্ট্যাক দিয়ে শুরু করছি fors এবং ifসঙ্গে গুলি yield xভিতরে। এটিকে জেনারেটর এক্সপ্রেশনে রূপান্তর করতে, xপ্রথমে সরান , সমস্ত কলোন (এবং yield) মুছুন এবং পুরো জিনিসটিকে প্রথম বন্ধনীতে ঘিরে ফেলুন । পরিবর্তে একটি তালিকা বোধগম্য করতে, বাহ্যিক পেরেনগুলি বর্গাকার বন্ধনী দ্বারা প্রতিস্থাপন করুন।
কেন আর্নল্ড

91

setবিল্টিনের জন্য অপারেটর ওভারলোডিং :

>>> a = set([1,2,3,4])
>>> b = set([3,4,5,6])
>>> a | b # Union
{1, 2, 3, 4, 5, 6}
>>> a & b # Intersection
{3, 4}
>>> a < b # Subset
False
>>> a - b # Difference
{1, 2}
>>> a ^ b # Symmetric Difference
{1, 2, 5, 6}

স্ট্যান্ডার্ড লাইব্রেরি রেফারেন্স থেকে আরও বিশদ: প্রকার সেট করুন


টিউটোরিয়ালে, আংশিকভাবে docs.python.org/tutorial/datastructures.html#sets
এক্সটিএল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.