11. Standart Kütüphanenin Kısa Özeti — Bölüm II¶
Bu ikinci özet, profesyonel programlama ihtiyaçlarını destekleyen daha gelişmiş modülleri kapsar. Bu modüller nadiren küçük komut dosyalarında bulunur.
11.1. Çıktı Biçimlendirmesi¶
reprlib
modülü, büyük veya derinlemesine iç içe kapların kısaltılmış gösterimleri için özelleştirilmiş bir repr()
sürümünü sağlar:
>>> import reprlib
>>> reprlib.repr(set('supercalifragilisticexpialidocious'))
"{'a', 'c', 'd', 'e', 'f', 'g', ...}"
pprint
modülü, hem yerleşik hem de kullanıcı tanımlı nesnelerin yorumlayıcı tarafından okunabilecek şekilde yazdırılması üzerinde daha karmaşık kontrol sunar. Sonuç bir satırdan uzun olduğunda, “pretty printer” veri yapısını daha net bir şekilde ortaya çıkarmak için satır sonları ve girintiler ekler:
>>> import pprint
>>> t = [[[['black', 'cyan'], 'white', ['green', 'red']], [['magenta',
... 'yellow'], 'blue']]]
...
>>> pprint.pprint(t, width=30)
[[[['black', 'cyan'],
'white',
['green', 'red']],
[['magenta', 'yellow'],
'blue']]]
textwrap
modülü, metin paragraflarını belirli bir ekran genişliğine uyacak şekilde biçimlendirir:
>>> import textwrap
>>> doc = """The wrap() method is just like fill() except that it returns
... a list of strings instead of one big string with newlines to separate
... the wrapped lines."""
...
>>> print(textwrap.fill(doc, width=40))
The wrap() method is just like fill()
except that it returns a list of strings
instead of one big string with newlines
to separate the wrapped lines.
locale
modülü kültüre özgü veri biçimlerinden oluşan bir veritabanına erişmektedir. Yerel ortamın biçim işlevinin gruplandırma özniteliği, sayıları grup ayırıcılarıyla biçimlendirmek için doğrudan bir yol sağlar:
>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'English_United States.1252')
'English_United States.1252'
>>> conv = locale.localeconv() # get a mapping of conventions
>>> x = 1234567.8
>>> locale.format_string("%d", x, grouping=True)
'1,234,567'
>>> locale.format_string("%s%.*f", (conv['currency_symbol'],
... conv['frac_digits'], x), grouping=True)
'$1,234,567.80'
11.2. Şablonlamak¶
string
modülü birçok yönlü kullanıcılar tarafından düzenlemeye uygun basitleştirilmiş sözdizimine sahip şablon sınıfı Template
içerir. Bu, kullanıcıların uygulamayı değiştirmek zorunda kalmadan uygulamalarını özelleştirmelerini sağlar.
Format, geçerli Python tanımlayıcılarıyla (alfasayısal karakterler ve alt çizgiler) $
tarafından oluşturulan yer tutucu adlarını kullanır. Yer tutucuyu ayraçla çevrelemek, onu araya giren boşluklar olmadan daha alfasayısal harflerle takip etmenizi sağlar. $$
yazmak tek bir $
oluşturur:
>>> from string import Template
>>> t = Template('${village}folk send $$10 to $cause.')
>>> t.substitute(village='Nottingham', cause='the ditch fund')
'Nottinghamfolk send $10 to the ditch fund.'
substitute()
yöntemi, bir sözlükte veya anahtar sözcük bağımsız değişkeninde yer tutucu sağlandığında KeyError
öğesini yükseltir. Adres mektup birleştirme stili uygulamalar için, kullanıcı tarafından sağlanan veriler eksik olabilir ve safe_substitute()
yöntemi daha uygun olabilir — veriler eksikse yer tutucuları değiştirmez:
>>> t = Template('Return the $item to $owner.')
>>> d = dict(item='unladen swallow')
>>> t.substitute(d)
Traceback (most recent call last):
...
KeyError: 'owner'
>>> t.safe_substitute(d)
'Return the unladen swallow to $owner.'
Şablon alt sınıfları özel bir sınırlayıcı belirtebilir. Örneğin, bir fotoğraf tarayıcısı için toplu yeniden adlandırma yardımcı programı, geçerli tarih, görüntü sıra numarası veya dosya biçimi gibi yer tutucular için yüzde işaretlerini kullanmayı seçebilir:
>>> import time, os.path
>>> photofiles = ['img_1074.jpg', 'img_1076.jpg', 'img_1077.jpg']
>>> class BatchRename(Template):
... delimiter = '%'
...
>>> fmt = input('Enter rename style (%d-date %n-seqnum %f-format): ')
Enter rename style (%d-date %n-seqnum %f-format): Ashley_%n%f
>>> t = BatchRename(fmt)
>>> date = time.strftime('%d%b%y')
>>> for i, filename in enumerate(photofiles):
... base, ext = os.path.splitext(filename)
... newname = t.substitute(d=date, n=i, f=ext)
... print('{0} --> {1}'.format(filename, newname))
img_1074.jpg --> Ashley_0.jpg
img_1076.jpg --> Ashley_1.jpg
img_1077.jpg --> Ashley_2.jpg
Templating için başka bir uygulama, program mantığını birden çok çıktı biçiminin ayrıntılarından ayırmaktır. Bu, XML dosyaları, düz metin raporları ve HTML web raporları için özel şablonların değiştirilmesini mümkün kılar.
11.3. İkili Veri Kaydı Düzenleriyle Çalışma¶
struct
modülü, değişken uzunluklu ikili kayıt formatlarıyla çalışmak için pack()
ve unpack()
işlevlerini sağlar. Aşağıdaki örnek, zipfile
modülünü kullanmadan bir ZIP dosyasındaki başlık bilgilerinin nasıl döngüye alınacağını gösterir. Paket kodları "H"
ve "I"
sırasıyla iki ve dört baytlık işaretsiz sayıları temsil eder. "<"
, standart boyutta ve küçük endian bayt düzeninde olduklarını gösterir:
import struct
with open('myfile.zip', 'rb') as f:
data = f.read()
start = 0
for i in range(3): # show the first 3 file headers
start += 14
fields = struct.unpack('<IIIHH', data[start:start+16])
crc32, comp_size, uncomp_size, filenamesize, extra_size = fields
start += 16
filename = data[start:start+filenamesize]
start += filenamesize
extra = data[start:start+extra_size]
print(filename, hex(crc32), comp_size, uncomp_size)
start += extra_size + comp_size # skip to the next header
11.4. Çoklu iş parçacığı¶
Diş açma, sıralı olarak bağımlı olmayan görevlerin ayrıştırılması için bir tekniktir. Diğer görevler arka planda çalışırken kullanıcı girdisini kabul eden uygulamaların yanıt verme hızını artırmak için iş parçacıkları kullanılabilir. İlgili bir kullanım durumu, başka bir iş parçacığındaki hesaplamalara paralel olarak I/O çalıştırmaktadır.
Aşağıdaki kod, ana program çalışmaya devam ederken üst düzey threading
modülünün görevleri arka planda nasıl çalıştırabileceğini gösterir:
import threading, zipfile
class AsyncZip(threading.Thread):
def __init__(self, infile, outfile):
threading.Thread.__init__(self)
self.infile = infile
self.outfile = outfile
def run(self):
f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
f.write(self.infile)
f.close()
print('Finished background zip of:', self.infile)
background = AsyncZip('mydata.txt', 'myarchive.zip')
background.start()
print('The main program continues to run in foreground.')
background.join() # Wait for the background task to finish
print('Main program waited until background was done.')
Çok iş parçacıklı uygulamaların temel zorluğu, verileri veya diğer kaynakları paylaşan iş parçacıklarını koordine etmektir. Bu amaçla, iş parçacığı modülü, kilitler, olaylar, koşul değişkenleri ve semaforlar dahil olmak üzere bir dizi senkronizasyon ilkesi sağlar.
Bu araçlar güçlü olsa da, küçük tasarım hataları, yeniden üretilmesi zor sorunlara neden olabilir. Bu nedenle, görev koordinasyonuna yönelik tercih edilen yaklaşım, bir kaynağa tüm erişimi tek bir iş parçacığında yoğunlaştırmak ve ardından bu iş parçacığını diğer iş parçacıklarından gelen isteklerle beslemek için queue
modülünü kullanmaktır. İş parçacıkları arası iletişim ve koordinasyon için Queue
nesnelerini kullanan uygulamaların tasarımı daha kolay, daha okunaklı ve daha güvenilirdir.
11.5. Günlükleme¶
logging
modülü, tam özellikli ve esnek bir kayıt sistemi sunar. En basit haliyle, günlük mesajları bir dosyaya veya sys.stderr
adresine gönderilir:
import logging
logging.debug('Debugging information')
logging.info('Informational message')
logging.warning('Warning:config file %s not found', 'server.conf')
logging.error('Error occurred')
logging.critical('Critical error -- shutting down')
Bu, aşağıdaki çıktıyı üretir:
WARNING:root:Warning:config file server.conf not found
ERROR:root:Error occurred
CRITICAL:root:Critical error -- shutting down
Varsayılan olarak, bilgi ve hata ayıklama mesajları bastırılır ve çıktı standart hataya gönderilir. Diğer çıktı seçenekleri, mesajları e-posta, datagramlar, yuvalar veya bir HTTP Sunucusuna yönlendirmeyi içerir. Yeni filtreler mesaj önceliğine göre farklı yönlendirme seçebilir: DEBUG
, INFO
, WARNING
, ERROR
, ve CRITICAL
.
Günlük kaydı sistemi, doğrudan Python’dan yapılandırılabilir veya uygulamayı değiştirmeden özelleştirilmiş günlük kaydı için kullanıcı tarafından düzenlenebilir bir yapılandırma dosyasından yüklenebilir.
11.6. Zayıf Başvurular¶
Python otomatik bellek yönetimi yapar (çoğu nesne için referans sayımı ve döngüleri ortadan kaldırmak için garbage collection). Hafıza, ona yapılan son başvurunun ortadan kaldırılmasından kısa bir süre sonra serbest bırakılır.
Bu yaklaşım çoğu uygulama için iyi sonuç verir ancak bazen nesneleri yalnızca başka bir şey tarafından kullanıldıkları sürece izlemeye ihtiyaç duyulur. Ne yazık ki, sadece onları izlemek onları kalıcı kılan bir referans oluşturur. weakref
modülü, referans oluşturmadan nesneleri izlemek için araçlar sağlar. Nesneye artık ihtiyaç duyulmadığında, zayıf referans tablosundan otomatik olarak kaldırılır ve zayıf referans nesneleri için bir geri arama tetiklenir. Tipik uygulamalar, oluşturması pahalı olan nesneleri önbelleğe almayı içerir:
>>> import weakref, gc
>>> class A:
... def __init__(self, value):
... self.value = value
... def __repr__(self):
... return str(self.value)
...
>>> a = A(10) # create a reference
>>> d = weakref.WeakValueDictionary()
>>> d['primary'] = a # does not create a reference
>>> d['primary'] # fetch the object if it is still alive
10
>>> del a # remove the one reference
>>> gc.collect() # run garbage collection right away
0
>>> d['primary'] # entry was automatically removed
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
d['primary'] # entry was automatically removed
File "C:/python314/lib/weakref.py", line 46, in __getitem__
o = self.data[key]()
KeyError: 'primary'
11.7. Listelerle Çalışma Araçları¶
Birçok veri yapısı ihtiyacı yerleşik liste türüyle karşılanabilir. Ancak bazen farklı performans ödünleşimleri ile alternatif uygulamalara ihtiyaç duyulmaktadır.
The array
module provides an array
object that is like
a list that stores only homogeneous data and stores it more compactly. The
following example shows an array of numbers stored as two byte unsigned binary
numbers (typecode "H"
) rather than the usual 16 bytes per entry for regular
lists of Python int objects:
>>> from array import array
>>> a = array('H', [4000, 10, 700, 22222])
>>> sum(a)
26932
>>> a[1:3]
array('H', [10, 700])
The collections
module provides a deque
object
that is like a list with faster appends and pops from the left side but slower
lookups in the middle. These objects are well suited for implementing queues
and breadth first tree searches:
>>> from collections import deque
>>> d = deque(["task1", "task2", "task3"])
>>> d.append("task4")
>>> print("Handling", d.popleft())
Handling task1
unsearched = deque([starting_node])
def breadth_first_search(unsearched):
node = unsearched.popleft()
for m in gen_moves(node):
if is_goal(m):
return m
unsearched.append(m)
Alternatif liste uygulamalarına ek olarak, kütüphane ayrıca sıralanmış listeleri işlemek için işlevlere sahip bisect
modülü gibi başka araçlar da sunar:
>>> import bisect
>>> scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')]
>>> bisect.insort(scores, (300, 'ruby'))
>>> scores
[(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]
heapq
modülü, düzenli listelere dayalı yığınları uygulamak için işlevler sağlar. En düşük değerli giriş her zaman sıfır konumunda tutulur. Bu, en küçük öğeye tekrar tekrar erişen ancak tam liste sıralamasını çalıştırmak istemeyen uygulamalar için kullanışlıdır:
>>> from heapq import heapify, heappop, heappush
>>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
>>> heapify(data) # rearrange the list into heap order
>>> heappush(data, -5) # add a new entry
>>> [heappop(data) for i in range(3)] # fetch the three smallest entries
[-5, 0, 1]
11.8. Decimal Floating-Point Arithmetic¶
The decimal
module offers a Decimal
datatype for
decimal floating-point arithmetic. Compared to the built-in float
implementation of binary floating point, the class is especially helpful for
tam ondalık gösterim gerektiren finansal uygulamalar ve diğer kullanımlar,
hassasiyet üzerinde kontrol,
yasal veya düzenleyici gereklilikleri karşılamak için yuvarlama üzerinde kontrol,
önemli ondalık basamakların izlenmesi veya
kullanıcının sonuçların elle yapılan hesaplamalarla eşleşmesini beklediği uygulamalar.
Örneğin, 70 sentlik bir telefon ücretinde 5% vergi hesaplamak ondalık kayan nokta ve ikili kayan nokta için farklı sonuçlar verir. Sonuçlar en yakın küsurata yuvarlanırsa fark önemli hale gelir:
>>> from decimal import *
>>> round(Decimal('0.70') * Decimal('1.05'), 2)
Decimal('0.74')
>>> round(.70 * 1.05, 2)
0.73
Decimal
sonucu, iki basamaklı anlamlı çarpanlardan otomatik olarak dört basamaklı anlamlılık çıkaran, sonunda bir sıfır tutar. Ondalık, matematiği elle yapıldığı gibi yeniden üretir ve ikili kayan nokta ondalık miktarları tam olarak temsil edemediğinde ortaya çıkabilecek sorunları önler.
Tam gösterim, Decimal
sınıfının, ikili kayan nokta için uygun olmayan modlo hesaplamaları ve eşitlik testleri gerçekleştirmesini sağlar:
>>> Decimal('1.00') % Decimal('.10')
Decimal('0.00')
>>> 1.00 % 0.10
0.09999999999999995
>>> sum([Decimal('0.1')]*10) == Decimal('1.0')
True
>>> 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 == 1.0
False
decimal
modülü, aritmetikle birlikte gerektiği kadar hassasiyet sağlar:
>>> getcontext().prec = 36
>>> Decimal(1) / Decimal(7)
Decimal('0.142857142857142857142857142857142857')