[ Pobierz całość w formacie PDF ]
.Chociaż SWIG wie, że konstruktory zwracają pamięć zaalokowaną, to nie może wiedzieć, że ta funkcja zwraca nowy obiekt, który musi być uwolniony przy usunięciu.Dyrektywa %new informuje SWIG o zwróceniu przez funkcję nowego obiektu.Na koniec, zmieniamy definicję atrybutu s_aliases tak, aby zdefiniować ją, jako wartość struct servent_alias *:%name(name) char *s_name;%name(aliases) struct servent_alias *s_aliases;%name(port) int s_port;Teraz można już przetestować obiekt iteratora.Utworzymy kopię obiektu servent dla protokołu discard:>>> import servtyp>>> i = servtyp.servent('discard')Teraz tworzymy odsyłacz dla atrybutu aliases kopii obiektu servent aby uzyskać kopię struktury servent_alias:>>> print i.aliases'_80f67f8_struct_servent_alias_p'I tu niemiła niespodzianka.To nie to, czego oczekiwaliśmy — otrzymaliśmy kopię struktury servent_alias, ale nie jest ona owinięta w odpowiednią dla niej klasę towarzyszącą (ang.shadow class) Pythona.Nie ma zatem sposobu, aby operator Pythona for mógł wywołać metodę specjalną __getitem__ dla tej kopii struktury.Można zrozumieć powody wystąpienia tego problemu, analizując plik towarzyszący servtyp.py:class serventPtr :def aliases_get(self):""""""val = servtypc.servent_aliases_get(self.this)val = servent_aliasPtr(val)val.thisown = 1return valdef __getattr__(self,name):if name == "aliases" :return servtypc.servent_aliases_get(self.this)Ten zmodyfikowany przykład pokazuje, że w czasie uzyskiwania wartości aliases ze struktury servent za pomocą metody getattr, określona w pliku owijającym funkcja servent_aliases_get jest wywołana bezpośrednio.Mimo, że funkcja aliases_get wykonuje to samo wywołanie funkcji owijającej, to przed zwróceniem otrzymanej wartości zostaje jeszcze objęta kapsułką kopii servent_aliasPtr.Można teraz porównać wartość nazwy zastępczej otrzymanej powyżej z wartością zwróconą przez aliases_get:>>> print i.aliases_get()<C servent_alias instance>Pokazuje to poważne ograniczenie w wersji SWIG, użytej do utworzenia tych przykładów.Chociaż SWIG poprawnie zachowuje się wobec funkcji aliases_get i wie, że aliases_get zastępuje domyślną funkcję owijającą dla atrybutu aliases, to jednak nie dokonuje właściwego dostrojenia funkcji owijającej, poprzez objęcie wartości atrybutu w kapsułkę kopii servent_aliasPtr.Używana przez Czytelnika wersja SWIG być może nie posiada tego ograniczenia.My tymczasem, zamiast realizować dostęp do atrybutu aliases, użyjemy bezpośrednio funkcji aliases_get.Kontynuując testowanie struktury servent_alias, można wywołać specjalną metodę Pythona __getitem__ używając wzrastającej wartości indeksu:>>> print i.aliases_get()[0]'sink'>>> print i.aliases_get()[1]'null'>>> print i.aliases_get()[2]Traceback (innermost last):File "<stdin>", line 1, in ?File "servtyp.py", line 10, in __getitem__val = servtypc.servent_alias__getitem__(self.this,arg0)IndexError: index out of bounds>>>Metoda specjalna servent_alias__getitem__ zgłasza wyjątek typu IndexError, kiedy wartość indeksu jest poza zakresem.Kopia servent_aliases może być użyta wraz z operatorem Pythona for w sposób następujący:>>> for alias in i.aliases_get():.print alias.sinknull>>>Korekta problemu pojedynczej kopiiJak to wzmiankowano, konstruktor servent zwraca tę samą kopię (ang.copy) struktury servent ponieważ biblioteka C zwraca wskaźnik do obiektu statycznego.Aby temu zaradzić, trzeba przekonać konstruktor servent, aby zwrócił jakąś kopię tej struktury, zamiast wskaźnika do pojedynczego statycznego egzemplarza dostarczonego przez bibliotekę C.Można tego dokonać z pomocą funkcji owijającej, którą nazwiemy CopyServent.Jej zadanie polega na utworzeniu nowej dynamicznej kopii struktury servent, wraz z nazwami zastępczymi.Kod nie jest charakterystyczny dla Pythona, ale trzeba będzie poprawić jakość poniższych przykładów.Należy zauważyć, że poniższy kod zawiera bardzo oszczędną kontrolę błędów i szacunkowe założenia, co do rozmiarów struktury.Kontrola błędów została pominięta ze względu na szczupłość miejsca oraz dla uproszczenia przykładu.Należy zmienić plik servtyp [ Pobierz całość w formacie PDF ]
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • centka.pev.pl
  •