python - पायथन की छिपी हुई विशेषताएं




hidden-features (20)

पाइथन प्रोग्रामिंग भाषा की कम ज्ञात लेकिन उपयोगी विशेषताएं क्या हैं?

  • पायथन कोर के उत्तरों को सीमित करने का प्रयास करें।
  • प्रति जवाब एक सुविधा।
  • फीचर का एक लिंक न केवल सुविधा का एक उदाहरण और संक्षिप्त विवरण दें।
  • पहली पंक्ति के रूप में शीर्षक का उपयोग करके सुविधा को लेबल करें।

उत्तर के त्वरित लिंक:


चेनिंग तुलना ऑपरेटर:

>>> 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 में अनुवाद कर 1 < x and x < 10 , और x < 10 and 10 < x * 10 and x*10 < 100 , लेकिन कम टाइपिंग के साथ और प्रत्येक शब्द का मूल्यांकन केवल एक बार किया जाता है।


नए प्रकार को पूरी तरह से गतिशील तरीके से बनाना

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

जो बिल्कुल वैसा ही है

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

शायद सबसे उपयोगी बात नहीं है, लेकिन जानना अच्छा है।

संपादित करें : नए प्रकार का फिक्स्ड नाम, class स्टेटमेंट के समान सटीक चीज़ होने के लिए NewType होना चाहिए।

संपादित करें : सुविधा का अधिक सटीक वर्णन करने के लिए शीर्षक समायोजित करें


शब्दकोशों में एक () विधि है

शब्दकोशों में 'get ()' विधि होती है। यदि आप डी ['कुंजी'] करते हैं और कुंजी नहीं है, तो आपको अपवाद मिलता है। यदि आप d.get ('key') करते हैं, तो आप वापस नहीं जाते हैं अगर 'कुंजी' नहीं है तो कोई नहीं। आप उस आइटम को किसी के बजाय वापस पाने के लिए दूसरा तर्क जोड़ सकते हैं, उदाहरण के लिए: d.get ('key', 0)।

संख्याओं को जोड़ने जैसी चीज़ों के लिए यह बहुत अच्छा है:

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


Doctest : documentation and unit-testing at the same time.

Example extracted from the Python documentation:

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()

2.5 से आगे की __missing__ एक विशेष विधि __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]}

defaultdict नामक defaultdict में एक defaultdict जो काफी समान करता है लेकिन मौजूदा आइटम के लिए तर्क के बिना फ़ंक्शन को कॉल करता है:

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

मैं इस तरह के उप-वर्गों की उम्मीद नहीं करने वाले कार्यों में गुजरने से पहले इस तरह के डिक्ट्स को नियमित डिक में परिवर्तित करने की अनुशंसा करता हूं। बहुत सारे कोड d[a_key] का उपयोग करते हैं और यह जांचने के लिए KeyErrors को पकड़ता है कि कोई आइटम मौजूद है या नहीं, जिसमें एक नया आइटम होगा।


ROT13 स्रोत कोड के लिए एक वैध एन्कोडिंग है, जब आप कोड फ़ाइल के शीर्ष पर सही कोडिंग घोषणा का उपयोग करते हैं:

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

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

टुकड़ा ऑपरेटरों में कदम तर्क। उदाहरण के लिए:

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]

यदि आपको स्कोप्स को इंगित करने के लिए व्हाइटस्पेस का उपयोग करना पसंद नहीं है, तो आप जारी करके सी-स्टाइल {} का उपयोग कर सकते हैं:

from __future__ import braces

Conditional Assignment

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

It does exactly what it sounds like: "assign 3 to x if y is 1, otherwise assign 2 to x". Note that the parens are not necessary, but I like them for readability. You can also chain it if you have something more complicated:

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

Though at a certain point, it goes a little too far.

Note that you can use if ... else in any expression. उदाहरण के लिए:

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

Here func1 will be called if y is 1 and func2, otherwise. In both cases the corresponding function will be called with arguments arg1 and arg2.

Analogously, the following is also valid:

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

where class1 and class2 are two classes.


Interactive Interpreter Tab Completion

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()

You will also have to set a PYTHONSTARTUP environment variable.


Main messages :)

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

De-cyphered :

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
सरल जटिल से बेहतर है।
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than right now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!


Operator overloading for the set builtin:

>>> 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}

मानक पुस्तकालय संदर्भ से अधिक जानकारी: सेट प्रकार


अपने regex डीबग करने के लिए पाइथन regex पार्स पेड़ प्राप्त करें।

नियमित अभिव्यक्ति अजगर की एक महान विशेषता है, लेकिन उन्हें डिबग करना दर्द हो सकता है, और रेगेक्स गलत होने के लिए यह बहुत आसान है।

सौभाग्य से, पायथन re.DEBUG पार्स पेड़ को re.DEBUG , प्रयोगात्मक, छुपा झंडा re.DEBUG (वास्तव में, 128) को re.compile से 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] [] से बचने के लिए भूल गया था।

निस्संदेह आप इसे जो भी झंडे चाहते हैं उसके साथ जोड़ सकते हैं, जैसे टिप्पणी regexes:

>>> 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)

इन-प्लेस वैल्यू स्वैपिंग

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

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

असाइनमेंट का दायां हाथ एक अभिव्यक्ति है जो एक नया ट्यूपल बनाता है। असाइनमेंट के बाएं हाथ की ओर तुरंत a ( b ) नामों के लिए उस (अप्रतिबंधित) tuple unpacks।

असाइनमेंट के बाद, नया टुपल अव्यवस्थित है और कचरा संग्रह के लिए चिह्नित है, और a और b जुड़े मूल्यों को बदल दिया गया है।

जैसा कि डेटा संरचनाओं पर पायथन ट्यूटोरियल अनुभाग में उल्लेख किया गया है,

ध्यान दें कि एकाधिक असाइनमेंट वास्तव में सिर्फ ट्यूपल पैकिंग और अनुक्रम अनपॅकिंग का संयोजन है।


जेनरेटर ऑब्जेक्ट्स बनाना

यदि आप लिखते हैं

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

आप जेनरेटर निकाल सकते हैं और इसे x को असाइन कर सकते हैं। अब इसका मतलब है कि आप कर सकते हैं

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)

पढ़ने योग्य नियमित अभिव्यक्तियां

पायथन में आप कई पंक्तियों पर एक नियमित अभिव्यक्ति विभाजित कर सकते हैं, अपने मैचों का नाम दे सकते हैं और टिप्पणियां डाल सकते हैं।

उदाहरण वर्बोज सिंटैक्स ( डाइव से पायथन में ):

>>> 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)

उदाहरण नामकरण मिलान ( नियमित अभिव्यक्ति HOWTO से )

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

आप शाब्दिक concatenation स्ट्रिंग करने के लिए re.VERBOSE धन्यवाद का उपयोग किए बिना एक regex भी verbosely लिख सकते हैं।

>>> 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})$"

फंक्शन तर्क अनपॅकिंग

आप * और ** का उपयोग करके फ़ंक्शन तर्क के रूप में किसी सूची या शब्दकोश को अनपैक कर सकते हैं।

उदाहरण के लिए:

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)

सूचियों, tuples और dicts के बाद से बहुत उपयोगी शॉर्टकट व्यापक रूप से कंटेनरों के रूप में उपयोग किया जाता है।


संदर्भ प्रबंधकों और " with " वक्तव्य

पीईपी 343 में पेश किया गया, एक संदर्भ प्रबंधक एक ऐसा ऑब्जेक्ट है जो बयान के सूट के लिए रन-टाइम संदर्भ के रूप में कार्य करता है।

चूंकि सुविधा नए कीवर्ड का उपयोग करती है, इसलिए इसे धीरे-धीरे पेश किया जाता है: यह __future__ निर्देश के माध्यम से पायथन 2.5 में उपलब्ध है। पायथन 2.6 और ऊपर (पायथन 3 सहित) यह डिफ़ॉल्ट रूप से उपलब्ध है।

मैंने "साथ" कथन का बहुत उपयोग किया है क्योंकि मुझे लगता है कि यह एक बहुत ही उपयोगी निर्माण है, यहां एक त्वरित डेमो है:

from __future__ import with_statement

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

दृश्यों के पीछे यहां क्या हो रहा है, यह है कि "साथ" कथन फ़ाइल ऑब्जेक्ट पर विशेष __enter__ और __exit__ विधियों को कॉल करता है। अपवाद विवरण __exit__ को भी पारित किया __exit__ यदि किसी अपवाद को बयान निकाय निकाय से उठाया गया था, जिससे वहां अपवाद हैंडलिंग की अनुमति मिलती है।

इस विशेष मामले में आपके लिए यह क्या करता है कि यह गारंटी देता है कि फ़ाइल बंद हो जाती है जब निष्पादन सूट के दायरे से बाहर हो जाता है, भले ही यह सामान्य रूप से होता है या कोई अपवाद फेंक दिया गया हो। यह मूल रूप से आम अपवाद-हैंडलिंग कोड को दूर करने का एक तरीका है।

इसके लिए अन्य सामान्य उपयोग मामलों में धागे और डेटाबेस लेनदेन के साथ लॉकिंग शामिल है।


Exception else clause:

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

The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn't raised by the code being protected by the try ... except statement.

See http://docs.python.org/tut/node10.html


Nested list comprehensions and generator expressions:

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

These can replace huge chunks of nested-loop code.







hidden-features