• Aucun résultat trouvé

A VERY LOOSE PROTOCOL

Dans le document Pro Django (Page 38-41)

File-like objects come in many varieties, because this protocol is one of the loosest defined in all of Python.

There are quite a few features, from buffering output to allowing random access to data, that are inappropriate in some situations, so objects designed for those situations will typically just not implement the correspond-ing methods. For example, Django’s DpplNaolkjoa object, described in Chapter 7, only allows writes in sequence, so it doesn’t implement na]`$%, oaag$% or pahh$%, causing errors when used with certain file- manipulation libraries.

The common approach in situations like this is to simply leave any inappropriate methods unimple-mented so that trying to access them raises an =ppne^qpaAnnkn. In other cases, a programmer may decide it’s more useful to implement them but simply raise a JkpEilhaiajpa`Annkn to display a more descriptive message. Just make sure to always document how much of the protocol your object obeys, so users aren’t surprised if these errors occur while trying to use them as standard files, especially in third- party libraries.

4. dppl6++lnk`f]jck*_ki+beha)iapdk`o+

Iterables

An object is considered iterable if passing it to the built- in epan$% returns an iterator. epan$%

is often called implicitly, as in a bkn loop. All lists, tuples and dictionaries are iterable, and any new- style class can be made iterable by defining the following method.

__iter__(self)

This method is called implicitly by epan$% and is responsible for returning an iterator that Python can use to retrieve items from the object. The iterator returned is often implied by defining this method as a generator function, described in the upcoming “Generators” section.

:::_h]ooBe^kj]__e$k^fa_p%6

***`ab[[ejep[[$oahb(_kqjp%6

***oahb*_kqjp9_kqjp

***`ab[[epan[[$oahb%6

***](^9,(-***bkntejn]jca$oahb*_kqjp%6

***ebt8.6

***ueah`t

***ahoa6

***_9]'^

***ueah`_

***](^9^(_

***

:::bkntejBe^kj]__e$1%6

***lnejpt(

***

,--./

:::bkntejBe^kj]__e$-,%6

***lnejpt(

***

,--./14-/.-/0

Iterators

When epan$% is called with an object, it’s expected to return an iterator, which can then be used to retrieve items for that object in sequence. Iterators are a simple method of one- way travel through the available items, returning just one at a time until there are no more to use.

For large collections, accessing items one by one is much more efficient than first gathering them all into a list.

next(self)

The only method required for an iterator, this returns a single item. How that item is retrieved will depend on what the iterator is designed for, but it must return just one item. After that item has been processed by whatever code called the iterator, jatp$% will be called again to retrieve the next item.

Once there are no more items to be returned, jatp$% is also responsible for telling Python to stop using the iterator and to move on after the loop. This is done by raising the OpklEpan]pekj exception. Python will continue calling jatp$% until an exception is raised, causing an infinite loop. Either OpklEpan]pekj should be used to stop the loop gracefully or another exception should be used to indicate a more serious problem.

_h]ooBe^kj]__eEpan]pkn$k^fa_p%6

`ab[[ejep[[$oahb(_kqjp%6 oahb*]9,

oahb*^9-oahb*_kqjp9_kqjp oahb*_qnnajp9,

`abjatp$oahb%6

oahb*_qnnajp'9-eboahb*_qnnajp:oahb*_kqjp6 n]eoaOpklEpan]pekj eboahb*_qnnajp8/6 napqnjoahb*_qnnajp)-_9oahb*]'oahb*^

oahb*]9oahb*^

oahb*^9_

napqnj_

`ab[[epan[[$oahb%6

Oej_aep#o]hna]`u]jepan]pkn(pdeo_]jnapqnjepoahb*

napqnjoahb _h]ooBe^kj]__e$k^fa_p%6

`ab[[ejep[[$oahb(_kqjp%6 oahb*_kqjp9_kqjp

`ab[[epan[[$oahb%6

napqnjBe^kj]__eEpan]pkn$oahb*_kqjp%

Note that iterators don’t explicitly need to define [[epan[[$% in order to be used properly, but including that method allows the iterator to be used directly in loops.

Generators

As illustrated in the Fibonacci examples, generators are a convenient shortcut to create simple iterators without having to define a separate class. Python uses the presence of the ueah` state-ment to identify a function as a generator, which makes it behave a bit differently from other functions.

When calling a generator function, Python doesn’t execute any of its code immediately.

Instead, it returns an iterator whose jatp$% method will then call the body of the function, up to the point where the first ueah` statement occurs. The expression given to the ueah` statement is used as the jatp$% method’s return value, allowing whatever code called the generator to get a value to work with.

The next time jatp$% is called on the iterator, Python continues executing the generator function right where it left off, with all of its variables intact. This repeats as long as Python encounters ueah` statements, typically with the function using a loop to keep yielding values.

Whenever the function finishes without yielding a value, the iterator automatically raises OpklEpan]pekj to indicate that the loop should be ended and the rest of the code can continue.

Sequences

While iterables simply describe an object that retrieves one value at a time, these values are often all known in advance and collected on a single object. This is a sequence. The most common types are lists and tuples. As iterables, sequences also use the [[epan[[$% method to return their values one by one, but since these values are also known in advance, some extra features are available.

__len__(self)

With all the values available, sequences have a specific length, which can be determined using the built- in haj$% function. Behind the scenes, haj$% checks to see if the object it’s given has a [[haj[[$% method and uses that to get the length of the sequence. To accomplish this, [[haj[[$% should return an integer containing the number of items in the sequence.

Technically, [[haj[[$% doesn’t require that all the values be known in advance, as long as it’s at least known how many values there will be. And since there can’t be partial items—an item either exists or it doesn’t—[[haj[[$% should always return an integer. If it doesn’t, haj$%

will coerce it to an integer anyway.

:::_h]ooBe^kj]__eHajcpd$Be^kj]__e%6

***`ab[[haj[[$oahb%6

***napqnjoahb*_kqjp

***

:::haj$Be^kj]__eHajcpd$-,%%

-,

:::haj$Be^kj]__eHajcpd$.,04%%

.,04

__getitem__() and __setitem__()

All the values in a sequence are already ordered as well, so it’s possible to access individual val-ues by their index within the sequence. Since the syntax used for this type of access is identical to that of dictionary keys, Python reuses the same two methods that were previously described for dictionaries. This allows a sequence to customize how individual values are accessed or perhaps restrict setting new values to the sequence, making it read- only.

Dans le document Pro Django (Page 38-41)