Alikirjainten erilainen käyttö nimeämissopimuksissa selitetty!!!
Alleviivausmerkkipisteen _
käyttäminen on erikoista Pythonissa. Vaikka alaviivaa käytetään monissa kielissä pelkkiä käärmemuuttujia ja funktioita varten, sillä on Pythonissa erityisiä merkityksiä. Niitä käytetään laajasti eri tilanteissa, kuten tapauksissa, joissa halutaan jättää jokin arvo huomiotta, tai muuttujien, metodien jne. ilmoittamisessa.
Yksittäisillä ja kaksinkertaisilla alleviivauksilla on oma merkityksensä Python-muuttujien ja metodien nimissä. Osa merkityksestä perustuu vain konventioon, kun taas osa on Python-tulkin pakottama.
Tässä artikkelissa käsittelemme viittä alleviivausmallia ja nimeämiskäytäntöä sekä sitä, miten ne vaikuttavat Python-ohjelmiemme käyttäytymiseen. Näiden käsitteiden ymmärtäminen auttaa paljon varsinkin kirjoittaessamme edistynyttä koodia.
Tämän kirjoituksen loppuun mennessä meillä on melko hyvä käsitys siitä, miten ja missä kannattaa käyttää mitä ja mitä alleviivauskuviota nimeämiskonventiossamme. Aloitetaan siis.
Single Leading Underscore: _var
Alleviivaus-etuliite on tarkoitettu vihjeeksi toiselle ohjelmoijalle, että yhdellä alleviivauksella alkava muuttuja tai metodi on tarkoitettu sisäiseen käyttöön. Tämä konventio on määritelty PEP 8:ssa.
Nimeä, jonka etuliitteenä on alleviivaus (esim.
_spam
), tulisi käsitellä API:n ei-julkisena osana (olipa kyseessä sitten funktio, metodi tai datajäsen). Sitä tulisi pitää toteutuksen yksityiskohtana ja sitä voidaan muuttaa ilman ennakkoilmoitusta.
Katsokaa seuraavaa esimerkkiä:
class Person:
def __init__(self):
self.name = 'Sarah'
self._age = 26
Tehdään yllä olevasta luokasta instanssi ja yritetään päästä käsiksi attribuutteihin name
ja _age
.
>>> p = Person()>>> p.name
Sarah>>> p._age
26
Yksittäinen alleviivaus-etuliite Pythonissa on siis vain sovittu konventio, eikä se aseta mitään rajoituksia kyseisen muuttujan arvon käyttämiselle.
Double Leading Underscore: __var
Kaksinkertaisen alleviivauksen (__
) käyttö nimen (erityisesti metodin nimen) edessä ei ole konventio, vaan sillä on erityinen merkitys tulkille.
Python mankeloi näitä nimiä ja sitä käytetään välttämään nimiristiriitoja alaluokkien määrittelemien nimien kanssa.
Tätä kutsutaan myös nimien mankeloinniksi – tulkki muuttaa muuttujan nimen siten, että törmäysten syntyminen on vaikeampaa, kun luokkaa laajennetaan myöhemmin.
Ymmärtääksemme paremmin, luomme leluluokkamme kokeilua varten:
class Person:
def __init__(self):
self.name = 'Sarah'
self._age = 26
self.__id = 30
Tarkastellaan sen objektin attribuutteja käyttämällä sisäänrakennettua dir()
-funktiota:
>>> p = Person()
>>> dir(p)
>>> p.name
Sarah
>>> p._age
26>>> p.__id
AttributeError: 'Person' object has no attribute '__id'>>> p._Person__id
30
Yllä olevasta objektin attribuuttiluettelosta näemme, että self.name
– ja self._age
-luokat näyttäytyvät muuttumattomina ja käyttäytyvät samalla tavalla.
Mutta __id
on muuttunut _Person__id
:ksi. Python-tulkki käyttää tätä nimien mankelointia. Se tekee tämän suojellakseen muuttujaa siltä, ettei sitä ylikirjoiteta alaluokissa.
Jos nyt luomme Person
:n alaluokan, vaikkapa Employee
, emme voi helposti ylikirjoittaa Person
:n __id
-muuttujaa.
Tarkoituksellinen käyttäytyminen tässä tapauksessa vastaa melkeinpä lopullisia (final) muuttujia Javassa ja ei-virtuaalisia (non virtual) muuttujia C++:ssa.
Single Trailing Underscore: var_
Kuten selitetään PEP 8:n dokumenteissa:
Single trailing underscore -nimityskonventiota käytetään välttämään ristiriitoja Pythonin avainsanojen kanssa.
Kun muuttujan sopivin nimi on jo varattu jollakin avainsanalla, noudatetaan yksinkertaisen alleviivauksen liittämistä nimiristiriitojen poistamiseksi. Tyypillinen esimerkki on class
tai muiden avainsanojen käyttäminen muuttujina.
>>> def method(name, class='Classname'): # ❌
SyntaxError: "invalid syntax">>> def method(name, class_='Classname'): # ✅
... pass
Double Leading and Trailing Underscore: __var__
Nimet, joissa on johtava ja perässä oleva kaksinkertainen alleviivaus (”dunders”), on varattu erityiskäyttöön, kuten __init__
-metodi objektien konstruktoreille tai __call__
-metodi, jolla objekti saadaan kutsuttavaksi. Nämä metodit tunnetaan nimellä dunder-metodit.
Sikäli kuin on kyse, tämä on vain konventio, Python-järjestelmän tapa käyttää nimiä, jotka eivät ole ristiriidassa käyttäjän määrittelemien nimien kanssa. Siksi dunderit ovat vain konventio, ja Python-tulkki jättää ne koskematta niihin.
class Person:
def __init__(self):
self.__name__ = 'Sarah'>>> Person().__name__
Sarah
Dunderit saavuttavat halutun tavoitteen tehdä tietyistä metodeista erikoisia, mutta samalla ne ovat kaikilta muilta osin samanlaisia kuin muut tavalliset metodit, lukuun ottamatta nimeämiskonventiota.
Todellisuudessa mikään ei estä meitä kirjoittamasta omia dunder-nimiämme, mutta on parasta pysytellä kaukana niiden käyttämisestä ohjelmissamme, jotta vältytään törmäyksiltä tulevien muutosten kanssa, jotka tulevat tapahtumaan Pythonin kieleen. (Katso tämä juttuni, jossa kerrotaan dundereista kattavasti).
Single Underscore: _
Konvention mukaan yksittäistä itsenäistä alaviivaa käytetään joskus nimenä ilmaisemaan, että muuttuja on väliaikainen tai merkityksetön.
Esimerkiksi seuraavassa silmukassa emme tarvitse pääsyä käynnissä olevaan indeksiin ja voimme käyttää ”_
” ilmaisemaan, että se on vain väliaikainen arvo:
>>> for _ in range(10):
... print('Welcome Sarah!!')
Jälleen kerran, tämä merkitys on vain ”konvention mukaan” eikä mitään erityiskäyttäytymistä laukaista Python-tulkissa. Yksittäinen alleviivaus on yksinkertaisesti kelvollinen muuttujan nimi, jota käytetään joskus tähän tarkoitukseen.
Johtopäätökset:
Erilaisen alleviivausmallin tunteminen auttaa kirjoittamaan koodimme pythonimaisemmaksi. 😄
Tässä on lyhyt yhteenveto edellä käsittelemistämme viidestä alleviivauskuviosta nimeämiskäytäntöjä varten.
- Yksittäinen johtava alleviivaus
_var
: Nimeämiskäytäntö, joka osoittaa nimen olevan tarkoitettu sisäiseen käyttöön. Vihje ohjelmoijille, eivätkä ohjelmoijat pakota sitä noudattamaan. - Double Leading Underscore
__var
: Laukaisee nimien sekoittamisen, kun sitä käytetään luokkayhteydessä. Python-tulkki pakottaa sen voimaan. - Single Trailing Underscore
var_
: Käytetään sopimuksen mukaan, jotta vältetään nimiristiriidat Python-avainsanojen kanssa. - Kaksinkertainen alaviiva
__var__
: Ilmaisee Python-kielen määrittelemiä erikoismetodeja. - Alaviiva
_
: Käytetään väliaikaisten muuttujien nimenä.