MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Atributele claselor și metodele statice

Atributele claselor

Pe lângă atributele obiectelor, în clase se pot defini și atribute ale claselor. Astfel de atribute sunt definite ca variabile la nivel de clasă. De exemplu:

class Person:
   type = "Person"
   description = "Describes a person"

print(Person.type)          # Person
print(Person.description)   # Describes a person

Person.type = "Class Person"
print(Person.type)          # Class Person

Aici, în clasa Person, sunt definite două atribute: type, care stochează numele clasei, și description, care stochează descrierea clasei.

Pentru a accesa atributele clasei, putem folosi numele clasei, de exemplu: Person.type, și, la fel ca atributele obiectului, putem obține și modifica valorile acestora.

Astfel de atribute sunt comune pentru toate obiectele clasei:

class Person:
   type = "Person"
   
   def __init__(self, name):
       self.name = name

tom = Person("Tom")
bob = Person("Bob")
print(tom.type)     # Person
print(bob.type)     # Person

# schimbăm atributul clasei
Person.type = "Class Person"
print(tom.type)     # Class Person
print(bob.type)     # Class Person

Atributele clasei pot fi utilizate în situațiile în care trebuie să definim anumite date comune pentru toate obiectele. De exemplu:

class Person:
   default_name = "Undefined"
   
   def __init__(self, name):
       if name:
           self.name = name
       else:
           self.name = Person.default_name

tom = Person("Tom")
bob = Person("")
print(tom.name)  # Tom
print(bob.name)  # Undefined

În acest caz, atributul default_name stochează numele implicit. Și dacă în constructor este transmis un șir de caractere gol pentru nume, atunci atributul name va primi valoarea atributului clasei default_name. Pentru a accesa atributul clasei în interiorul metodelor, putem folosi numele clasei:

self.name = Person.default_name

Atributul clasei și atributul obiectului

Este posibilă situația în care atributul clasei și atributul obiectului au același nume. Dacă în cod nu este setată o valoare pentru atributul obiectului, atunci pentru acesta poate fi folosită valoarea atributului clasei:

class Person:
   name = "Undefined"
   
   def print_name(self):
       print(self.name)

tom = Person()
bob = Person()
tom.print_name()    # Undefined
bob.print_name()    # Undefined

bob.name = "Bob"
bob.print_name()    # Bob
tom.print_n

Aici metoda print_name folosește atributul obiectului name, însă nicăieri în cod acest atribut nu este setat. Însă la nivelul clasei este definit atributul name. Prin urmare, la prima apelare a metodei print_name, în ea va fi folosită valoarea atributului clasei:

tom = Person()
bob = Person()
tom.print_name()    # Undefined
bob.print_name()    # Undefined


Ulterior, putem seta atributul obiectului:

bob.name = "Bob"
bob.print_name()    # Bob
tom.print_name()    # Undefined

În plus, al doilea obiect - tom va continua să folosească atributul clasei. Și dacă schimbăm atributul clasei, corespunzător valoarea tom.name se va schimba:

tom = Person()
bob = Person()
tom.print_name()    # Undefined
bob.print_name()    # Undefined

Person.name = "Some Person"     # schimbăm valoarea atributului clasei
bob.name = "Bob"                # setăm atributul obiectului
bob.print_name()    # Bob
tom.print_name()    # Some Person

Metode statice

Pe lângă metodele obișnuite, o clasă poate defini și metode statice. Aceste metode sunt precedate de anotarea @staticmethod și se referă în general la clasă. Metodele statice definesc de obicei un comportament care nu depinde de un anumit obiect:

class Person:
   __type = "Person"
   
    @staticmethod
   def print_type():
       print(Person.__type)

Person.print_type()     # Person - apelul metodei statice prin numele clasei

tom = Person()
tom.print_type()     # Person - apelul metodei statice prin numele obiectului

În acest caz, în clasa Person este definit atributul clasei __type, care stochează o valoare comună pentru întreaga clasă - numele clasei. Deoarece numele atributului este precedat de două liniuțe de subliniere, acest atribut va fi privat, ceea ce îl protejează de modificările neautorizate.

De asemenea, în clasa Person este definită metoda statică print_type, care afișează în consolă valoarea atributului __type. Acțiunea acestei metode nu depinde de un anumit obiect și se referă în general la întreaga clasă - indiferent de obiect, pe consolă va fi afișată aceeași valoare a atributului __type. De aceea, o astfel de metodă poate fi făcută statică.

← Lecția anterioară Lecția următoare →