Zanurkuj w Pythonie/Abstrakcyjne źródła wejścia: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Piotr (dyskusja | edycje)
Nie podano opisu zmian
Piotr (dyskusja | edycje)
ok, przetłumaczone
Linia 1:
{{WEdycji}}
 
{{Podświetl|py}}
== Abstrakcyjne źródła wejścia ==
Linia 134 ⟶ 132:
# Teraz możemy przekazać obiekt pliko-podobny (w rzeczywistości <tt>StringIO</tt>) do <tt>minidom.parse</tt>, który wywoła metodę <tt>read</tt> z tego obiektu i szczęśliwie wszystko przeparsuje, nie zdając sobie nawet sprawy, że wejście to pochodzi z łańcucha znaków.
 
To już wiemy, jak za pomocą pojedyńczej funkcji, <tt>minidom.parse</tt>, sparsować dokument XML przechowywany na stronie internetowej, lokalnym pliku, czy łańcuchu znaków. Dla strony internetowej wykorzystamy <tt>urlopen</tt>, aby dostać ''obiekt pliko-podobny''; dla lokalnego pliku, wykorzystamy <tt>open</tt>; a w przypadku łańcucha znaków skorzystamy z <tt>StringIO</tt>. Lecz teraz pójdźmy trochę do przodu i uogólnijmy też te różnice.
So now you know how to use a single function, minidom.parse, to parse an XML document stored on a web page, in a local file, or in a hard-coded string. For a web page, you use urlopen to get a file-like object; for a local file, you use open; and for a string, you use StringIO. Now let's take it one step further and generalize these differences as well.
 
'''ExamplePrzykład 10.6. <tt>openAnything</tt>'''
 
<nowiki>
Linia 158 ⟶ 156:
</nowiki>
 
# TheFunkcja <tt>openAnything</tt> functionprzyjmuje takespojedynczy a single parameterargument, <tt>source</tt>, andi returnszwraca a''obiekt filepliko-like objectpodobny''. <tt>source</tt> isjest ałańcuchem stringznaków ofo someróżnym sort;charakterze. itMoże cansię eitherodnosić bedo aadresu URL (likenp. <tt>'http://slashdot.org/slashdot.rdf'</tt>), amoże fullbyć orglobalną partiallub pathnamelokalną tościeżką ado local filepliku (likenp. <tt>'binary.xml'</tt>), orczy ateż stringłańcuchem thatznaków containsprzechowującym actualdokument XML, dataktóry toma bezostać parsedsparsowany.
# Najpierw sprawdzamy, czy <tt>source</tt> jest URL-em. Robimy to brutalnie: próbujemy otworzyć to jako URL i cicho pomijamy błędy spowodowane próbą otworzenia czegoś, co nie jest URL-em. Jest to właściwie eleganckie w tym sensie, że jeśli <tt>urllib</tt> będzie kiedyś obsługiwał nowe typy URL-i, nasz program także je obsłuży i to bez konieczności zmiany kodu. Jeśli <tt>urllib</tt> jest w stanie otworzyć <tt>source</tt>, to <tt>return</tt> wykopie nas bezpośrednio z funkcji i poniższe instrukcje <tt>try</tt> nie będą nigdy wykonywane.
# First, you see if source is a URL. You do this through brute force: you try to open it as a URL and silently ignore errors caused by trying to open something which is not a URL. This is actually elegant in the sense that, if urllib ever supports new types of URLs in the future, you will also support them without recoding. If urllib is able to open source, then the return kicks you out of the function immediately and the following try statements never execute.
# W innym przypadku, gdy <tt>urllib</tt> wrzasnął na nas i powiedział, że <tt>source</tt> nie jest poprawnym URL-em, zakładamy, że jest to ścieżka do pliku znajdującym się na dysku i próbujemy go otworzyć. Ponownie, nic nie robimy, by sprawdzić, czy <tt>source</tt> jest poprawną nazwą pliku (zasady określające poprawność nazwy pliku są szalenie różne na różnych platformach, dlatego prawdopodobnie i tak byśmy to źle zrobili). Zamiast tego, na ślepo otwieramy plik i cicho pomijamy wszystkie błędy.
# On the other hand, if urllib yelled at you and told you that source wasn't a valid URL, you assume it's a path to a file on disk and try to open it. Again, you don't do anything fancy to check whether source is a valid filename or not (the rules for valid filenames vary wildly between different platforms anyway, so you'd probably get them wrong anyway). Instead, you just blindly open the file, and silently trap any errors.
# W tym miejscu zakładamy, że <tt>source</tt> jest łańcuchem znaków, który przechowuje dokument XML (ponieważ nic innego nie zadziałało), dlatego wykorzystujemy <tt>StringIO</tt>, aby utworzyć ''obiekt pliko-podobny'' i zwracamy go. (Tak naprawdę, ponieważ wykorzystujemy funkcje <tt>str</tt>, <tt>source</tt> nie musi być nawet łańcuchem znaków; może być nawet dowolnym obiektem, a z którego zostanie wykorzystana jego tekstową <ref>łańcuchowo-znakowa</ref> reprezentacja, a która jest zdefiniowana przez specjalną metodę <tt>__str__</tt>.)
# By this point, you need to assume that source is a string that has hard-coded data in it (since nothing else worked), so you use StringIO to create a file-like object out of it and return that. (In fact, since you're using the str function, source doesn't even need to be a string; it could be any object, and you'll use its string representation, as defined by its __str__ special method.)
 
Teraz możemy wykorzystać funkcje <tt>openAnything</tt> w połączeniu z <tt>minidom.parse</tt>, aby utworzyć funkcje, która przyjmuje źródło <tt>source</tt>, które w jakiś sposób odwołuje się do dokumentu XML (może to robić za pomocą adresu URL, lokalnego pliku, czy też dokumentu przechowywanego jako łańcuch znaków), i parsuje je.
Now you can use this openAnything function in conjunction with minidom.parse to make a function that takes a source that refers to an XML document somehow (either as a URL, or a local filename, or a hard-coded XML document in a string) and parses it.
 
'''ExamplePrzykład 10.7. UsingWykorzystanie <tt>openAnything</tt> inw kgp.py'''
<nowiki>
class KantGenerator: