Portál AbcLinuxu, 15. května 2025 20:51
def f(x, a=[]): a.append(x) print(len(a)) f(1) f('ble') f(None)Dále: Všechno se předává referencí. Tedy všechno s čím pracuješ, jsou jména objektů, ne hodnoty. Existují modifikovatelné a nemodifikovatelné objekty. Nemodifikovatelné (např. čísla, stringy, None, ...) se chovají de facto jako hodnoty, ale právě jen proto, že nejdou modifikovat. Po x=1 jsou x a 1 jen jiná jména pro týž objekt. Po x+=1 bude x jméno pro jiný nemodifikovatelný objekt, nezmění se žádná hodnota x. A u modifikovatelných je to pak samozřejmě velký rozdíl. Chceš-li kopii, použij modul copy (např.).
Všechno se předává referencí. Tedy všechno s čím pracuješ, jsou jména objektů, ne hodnoty.Technicky vzato se vše předává hodnotou, která obsahuje referenci (tedy lokální název obsahuje stejnou referenci na objekt, jako „skutečný“ parametr). Předává se tedy (reference na) objekt, ne proměnná jako taková. Souhlasím s tím, že většina problémů bude způsobena tím, že se použije stejný měnitelný objekt, kde si programátor myslí, že se mu vytvoří nový objekt.
def __init__(self, name, parent, attrs = {}) self.__attrs = attrsslovník
attrs
se ti zkonstruje pouze jednou v okamžiku definice té funkce, všechny instance si následně přiřadí do svého jmenného prostoru referenci na tentýž slovník.
Správně se to dělá takhle:
def __init__(self, name, parent, attrs = None) self.attrs = attrs if attrs is not None else {}
Rada do života jako bonus: Nepiš gettery a settery! Je to nepřehledný hnus a zbytečně to zpomaluje. (Volání metody je v pythonu relativně drahá operace.) Pokud budeš někdy v budoucnu potřebovat udělat getter nebo setter, přístup k atributu se dá zachytit pomocí @property dekorátoru. To ostatně platí obecně – pythoní kód je stručný výstižný, pokud se přistihneš že píšeš nudnou "omáčku" ve stylu Javy tak děláš něco špatně.Gettery a settery jsou zločin i v Javě. Je to jasná ukázka, že dotyčný programátor neumí programovat objektově.
A proč bych měl přistupovat k hodnotám atributů objektu?Protože Python nemá POD (plain old data) schopná snadno a rychle shrnout skupinu informací do jedné ,věci`. Tudíž zbývá
# Dal jsem to do čtvrté položky, nebo do šesté? Ale kdeže, do třetí. struct = (1.2, -3.0, 'cx', 4, 4, 0, True, False, True) print struct[3] # Složitý přístup k datům máme rádi, nutí nás zamyslet se, zda je opravdu potřebujeme. struct = { 'alpha': 1.2, 'lambda': -3.0, 'name': 'cx', 'width': 4, 'height': 4, 'depth': 0, 'normalize': True, 'recursive': False, 'fixed': True, } print struct['width'] # Jsem expert, tak vyrobím něco, co se dá indexovat a sčítat jako tuple, abych vás zmátl. import collections Struct = collections.namedtuple('Struct', bla bla bla...) bla bla bla... # Ecce obiectum! Není to POD, ale je to skoro tak dobré. class Struct: def __init__(self, **kwargs): self.__dict__.update(kwargs) struct = Struct(alpha=1.2, beta=-3.0, name='cx', width=4, height=4, depth=0, normalize=True, recusrive=False, fixed=True) print struct.widthNavzdory ortodoxním objektistům nechci té věci posílat zprávy, chci s ní něco udělat (viz Execution in the Kingdom of Nouns). Právě proto, aby to nevypadalo jako typická javí byrokracie.
Někdy je také dobré se zamyslet, k čemu vlastně potřebujiA proč bych měl přistupovat k hodnotám atributů objektu?... print struct.width
struct.width
. Často je to zaviněno chybným návrhem objektu. Obvykle totiž samotné atributy objektu ve své podstatě nepotřebuji.
Gettery a settery mezi metody nepočítám. Jsou jen nadstavbou datové struktury, aby přímý přístup k ní nevypadal tak blbě.Blbost. V setteru bezne provadim vedlejsi efekty, napr. logging. Navic python pomoci property() vytvari tak dokonalou hracku, ze se to primo vybizi takto primo pristupovat k atributum objektu.
Byly myšleny primitivní gettery a settery v uvedeném příkladu, které jen nahrazovaly přímý přístup k datové struktuře a nedělaly nic navíc.Což je ovšem velmi nezajímavé téma, o kterém si tu podle mě chce povídat jen jeden jediný člověk.
I když je to po technické stránce objekt, má do objektu daleko.Ach ta terminologie :).
typedef struct list { char *data; struct list *next; } LIST;Ja se teda snazim presneji o tohle, coz sice neni to same, ale napadne podobne:
typedef struct list { char *data; struct list *parent; struct list **children; } LIST;Ale neprisel jsem na to, jak to zrealizovat v pythonu. V PHP to bylo hned, ale v pythonu porad tapu a tapu...
Protoze seznam nema reference mezi objekty nebo snad ano?Který části tvrzení „v pythonu je všechno reference“ nerozumíš?
In [10]: l = [1,2,3] In [11]: l.append(l) In [12]: l Out[12]: [1, 2, 3, [...]](tři tečky jsou objekt
Elipsis
který značí zacyklení)
Ale kazdopadne nic to nemeni na tom, ze se mi nedari zrealizovat klasicky seznam-like datovou strukturu - priklad:Definuj „nedaří se mi“, mně totiž nenapadá, co by se ti na tom mohlo nedařit. Atribut data nastavit můžeš, atribut next jakbysmet, takže?typedef struct list { char *data; struct list *next; } LIST;
Odpoved najdes v "test2.py" (2. reakce, v teto diskuzi)Pokud nemáš zájem o pomoc, stačí to říct rovnou :).
Nelíbí se mi, když kdekdo do třídy paušálně nacpe gettery a settery na každou položku, ke které možná bude chtít přistupovat z vnějšku. Je to stejně špatné, jako použití public proměnných. Jen to vypadá jinak.Nebo taky stejně správně :).
return this.prijmeni;a takové metody se mi nelíbí, protože nic nedělají. Možná to chápeš jinak. Velmi často se setkávám s tím, že v aplikaci je getter osoba.getPrijmeni(), o řádek níž osoba.getJmeno() a na dalším je jejich spojování a výstup. Proč tak složitě, když to může udělat objekt? Se settery to bývá stejné. Nejprve vytvoření prázdného objektu, potom hromada setterů. Přitom by stačilo jedním příkazem vytvořit naplněný objekt v konstruktoru. Další příklad. Připočtení hodnoty k atributu objektu. Běžně vídám tuto hrůzu:
objekt.setX(objekt.getX+5);místo praktičtějšího
objekt.addX(5);nebo
objekt.posunDoprava(5);případně
objekt.posun(5,kurs);
setCeleJmeno("Jmeno","Prijmeni")
class Zamestnanec(object): def __init__(self): self.jmeno = u"" self.prijmeni = u"" self.pozice = u""
Podle mne je to běžné parsování metodou SAX. Každý token vyvolá nějakou událost, kterou si zpracuješ podle potřeby.To je na něm špatně.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.