برنامه نویسی

مفاهیم OOP در پایتون برای برنامه نویسان C++98

Summarize this content to 400 words in Persian Lang

در اینجا یک نمایش کامل از مفاهیم OOP در پایتون برای یک برنامه نویس C++98 است:

تعریف کلاس و ایجاد شی

پایتون

# Privado por convenção: _underscore_simples
# “Realmente privado”: __underscore_duplo (name mangling)
# Público: sem underscore

class Animal:
# Variável de classe (compartilhada por todas as instâncias) pode ser inicializada diretamente
species_count = 0

# Construtor
def __init__(self, name):
# Variáveis de instância
self.name = name # público
self._age = 0 # protegido por convenção
self.__id = id(self) # privado (mas você consegue acessar com name mangling)
Animal.species_count += 1

# Destrutor
def __del__(self):
Animal.species_count -= 1

# Método regular
def make_sound(self):
pass # Equivalente a um método abstrato/virtual (não implementável na classe base)

# Método estático (não precisa de classe ou instância)
@staticmethod
def get_kingdom():
return “Animalia”

# Método de classe (recebe a classe como primeiro argumento)
@classmethod
def get_species_count(cls):
return cls.species_count

# Decorador de propriedade (getter)
@property
def age(self):
return self._age

# Decorador de propriedade (setter)
@age.setter
def age(self, value):
if value >= 0:
self._age = value

# Métodos especiais (sobrecarga de operadores)
def __str__(self): # Como toString() – para string legível
return f”Animal named {self.name}”

def __repr__(self): # Para debugging
return f”Animal(name='{self.name}’)”

def __eq__(self, other): # Operador de comparação ==
return isinstance(other, Animal) and self.name == other.name

def __len__(self): # Função len()
return self._age

def __getitem__(self, key): # Operador de acesso [] if key == ‘name’:
return self.name
raise KeyError(key)

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

#include
#include
#include

class Animal {
public:
static int species_count;

Animal(const std::string& name) : name(name), _age(0), __id(++id_counter) { // construtor
++species_count;
}

~Animal() { // destrutor
–species_count;
}

virtual void make_sound() = 0; // Método não implementável na classe base (virtual/abstrato)

// getters:
static std::string get_kingdom() {
return “Animalia”;
}

static int get_species_count() {
return species_count;
}

int get_age() const {
return _age;
}

// setter:
void set_age(int age) {
if (age >= 0) {
_age = age;
}
}

std::string to_string() const {
return “Animal named ” + name;
}

std::string repr() const {
std::ostringstream oss;
oss << “Animal(name=”” << name << “”, age=” << _age << “, id=” << __id << “)”;
return oss.str();
}

bool operator==(const Animal& other) const {
return name == other.name;
}

// Sobrecarga do operador [] std::string operator[](const std::string& key) const {
if (key == “name”) {
return name;
}
throw std::out_of_range(“Invalid key”);
}

// Método isinstance
template <typename T>
bool isinstance() const {
return dynamic_cast<const T*>(this) != nullptr;
}

protected:
std::string name;
int _age;

private:
int __id;
static int id_counter;
};

// variáveis estáticas de classe são compartilhadas por todas as instâncias mas
// precisam ser inicializadas separadamente.
int Animal::species_count = 0;
int Animal::id_counter = 0;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

میراث

پایتون

class Dog(Animal):
def __init__(self, name, breed):
# Chama o construtor da classe pai
super().__init__(name)
self.breed = breed

# Sobrescreve o método da classe pai
def make_sound(self):
return “Woof!”

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

class Dog : public Animal {
public:
Dog(const std::string& name, const std::string& breed) : Animal(name), breed(breed) {}

void make_sound() override {
std::cout << “Woof!” << std::endl;
}

private:
std::string breed;
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ارث چندگانه

پایتون

class Pet:
def is_vaccinated(self):
return True

class DomesticDog(Dog, Pet):
pass

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

class Pet {
public:
bool is_vaccinated() const {
return true;
}
};

class DomesticDog : public Dog, public Pet {
public:
DomesticDog(const std::string& name, const std::string& breed) : Dog(name, breed) {}
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

کلاس چکیده

پایتون

from abc import ABC, abstractmethod

class Shape(ABC):
@abstractmethod
def area(self):
pass

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

class Shape {
public:
virtual ~Shape() {}
virtual double area() const = 0;
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مثال استفاده

پایتون

if __name__ == “__main__”:
# Cria objetos
dog = Dog(“Rex”, “Golden Retriever”)

# Acessa atributos
print(dog.name) # Público
print(dog._age) # Protegido (ainda acessível)
# print(dog.__id) # Isso falhará
print(dog._Animal__id) # Isso funciona (acessando attribute privado com name mangling)

# Propriedades
dog.age = 5 # Usa setter automaticamente
print(dog.age) # Usa getter automaticamente

# Métodos estáticos e de classe
print(Animal.get_kingdom())
print(Animal.get_species_count())

# Verifica herança
print(isinstance(dog, Animal)) # True
print(issubclass(Dog, Animal)) # True

# Métodos especiais em ação
print(str(dog)) # Usa __str__
print(repr(dog)) # Usa __repr__
print(len(dog)) # Usa __len__
print(dog[‘name’]) # Usa __getitem__

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

int main() {
// Cria objetos
Dog dog(“Rex”, “Golden Retriever”);

// Acessa atributos
std::cout << dog.name << std::endl; // Público
std::cout << dog.get_age() << std::endl; // Protegido (ainda acessível)
// std::cout << dog.__id << std::endl; // Isso falhará (privado)

// Propriedades
dog.set_age(5); // Usa setter
std::cout << dog.get_age() << std::endl; // Usa getter

// Métodos estáticos e de classe
std::cout << Animal::get_kingdom() << std::endl;
std::cout << Animal::get_species_count() << std::endl;

// Equivalente aos “métodos especiais”:

// Verifica herança
if (dog.isinstance<Animal>()) {
std::cout << “dog é uma instância de Animal” << std::endl;
}

std::cout << dog.to_string() << std::endl; // Usa to_string
std::cout << dog.repr() << std::endl; // Usa repr
std::cout << dog[“name”] << std::endl; // Usa operador [] }

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تفاوت های کلیدی پایتون و C++98

بدون کلمات کلیدی عمومی/خصوصی/محافظت شده (استفاده از قراردادهای نامگذاری)
ارث چندگانه متفاوت است:

پایتون از ترتیب وضوح روش (MRO) با خطی سازی C3 استفاده می کند
بدون نیاز به وراثت مجازی مانند C++

super() به طور خودکار MRO را دنبال می کند
ترتیب کلاس های پایه در پایتون مهم است
شما می توانید دستور حل و فصل را با __mro__

همه متدها به صورت پیش فرض مجازی هستند
بدون نیاز به فایل های هدر
هیچ تمایزی بین اشاره گرها / ارجاعات وجود ندارد
بدون نیاز به مدیریت حافظه ( زباله جمع کن )
همه چیز یک شی است (از جمله توابع)
تایپ پویا به جای تایپ ایستا
دکوراتورهای املاک به جای روش های گیر/ستر
روش های خاص از قالب استفاده می کنند __name__ به جای کلمه کلیدی عملگر
سینتکس بیشتر پایتونیک برای بارگذاری بیش از حد اپراتور (به عنوان مثال __eq__ در مقابل operator==)

استفاده کنید dir(object) برای دیدن تمام ویژگی ها و روش های یک شی، و help(object) برای مستندسازی

مشکل ارث بری الماس

مشکلات وراثت الماس در C++98

وراثت الماس زمانی اتفاق می افتد که یک کلاس از دو کلاس ارث می برد که به نوبه خود از یک کلاس پایه مشترک ارث می برند. این می تواند چندین مشکل ایجاد کند:

ابهام: روش ها و ویژگی های کلاس پایه مشترک می توانند مبهم شوند.

تکثیر داده ها: هر کلاس مشتق شده می تواند کپی خود را از اعضای کلاس پایه مشترک داشته باشد که منجر به تکرار داده ها می شود.

مثال وراثت الماس در C++98

class Animal {
public:
Animal() {
std::cout << “Animal constructor” << std::endl;
}
virtual void make_sound() {
std::cout << “Some generic animal sound” << std::endl;
}
};

class Pet : public Animal {
public:
Pet() : Animal() {
std::cout << “Pet constructor” << std::endl;
}
void make_sound() override {
std::cout << “Pet sound” << std::endl;
}
};

class WorkingAnimal : public Animal {
public:
WorkingAnimal() : Animal() {
std::cout << “WorkingAnimal constructor” << std::endl;
}
void make_sound() override {
std::cout << “Working animal sound” << std::endl;
}
};

class DomesticDog : public Pet, public WorkingAnimal {
public:
DomesticDog() : Animal(), Pet(), WorkingAnimal() {
std::cout << “DomesticDog constructor” << std::endl;
}
void make_sound() override {
Pet::make_sound(); // Ou WorkingAnimal::make_sound(), dependendo do comportamento desejado
}
};

int main() {
DomesticDog dog;
dog.make_sound();
return 0;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

رفتار مورد انتظار

Animal constructor
Pet constructor
WorkingAnimal constructor
DomesticDog constructor
Pet sound

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مثال، DomesticDog گله از Pet ه WorkingAnimal، هر دو به ارث می برند Animal. این یک الماس موروثی ایجاد می کند. وراثت مجازی برای جلوگیری از تکرار و ابهام داده ها استفاده می شود.

چگونه پایتون به طور خودکار از ارث بری الماس جلوگیری می کند

پایتون از ترتیب وضوح روش (MRO) با خطی سازی C3 برای حل خودکار مسائل ارث بری الماس استفاده می کند. MRO هنگام جستجوی یک متد یا ویژگی، ترتیب بررسی کلاس ها را تعیین می کند.

مثال وراثت الماس در پایتون

class Animal:
def make_sound(self):
print(“Some generic animal sound”)

class Pet(Animal):
def make_sound(self):
print(“Pet sound”)

class WorkingAnimal(Animal):
def make_sound(self):
print(“Working animal sound”)

class DomesticDog(Pet, WorkingAnimal):
pass

dog = DomesticDog()
dog.make_sound()

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

رفتار مورد انتظار

Pet sound

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مثال، پایتون به طور خودکار وراثت الماس را با استفاده از MRO حل می کند. شما می توانید MRO را با استفاده از ویژگی بررسی کنید __mro__:

print(DomesticDog.__mro__)

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

MRO در پایتون این را تضمین می کند DomesticDog به درستی از Pet ه WorkingAnimal، و آن Animal قبل حل شود object. بنابراین، ترتیب اعلامیه بر MRO تأثیر می گذارد، اما خطی سازی C3 تضمین می کند که سلسله مراتب رعایت می شود.

توضیح:

دستور اعلامیه: MRO با مشتق ترین کلاس شروع می شود و از ترتیبی که طبقات پایه اعلام می شوند پیروی می کند.

خطی سازی C3: تضمین می کند که هر کلاس قبل از سوپرکلاس های خود ظاهر می شود و ترتیب وراثت حفظ می شود.

ساختارهای داده: پشته، صف و نقشه

پشته

پایتون

stack = [] # we could just use a list as a stack
stack.append(1) # push
stack.append(2)
print(stack.pop()) # pop

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

#include // we have to import the stack type
std::stack<int> stack;
stack.push(1); // push
stack.push(2);
std::cout << stack.top() << std::endl; // top
stack.pop(); // pop

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

صف

پایتون

from collections import deque
queue = deque()
queue.append(1) # enqueue
queue.append(2)
print(queue.popleft()) # dequeue

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

#include
std::queue<int> queue;
queue.push(1); // enqueue
queue.push(2);
std::cout << queue.front() << std::endl; // front
queue.pop(); // dequeue

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نقشه

پایتون

map = {}
map[‘key1’] = ‘value1’
map[‘key2’] = ‘value2’
print(map[‘key1’])

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

#include
std::map<std::string, std::string> map;
map[“key1”] = “value1”;
map[“key2”] = “value2”;
std::cout << map[“key1”] << std::endl;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در اینجا یک نمایش کامل از مفاهیم OOP در پایتون برای یک برنامه نویس C++98 است:

تعریف کلاس و ایجاد شی

پایتون

# Privado por convenção: _underscore_simples
# "Realmente privado": __underscore_duplo (name mangling)
# Público: sem underscore

class Animal:
    # Variável de classe (compartilhada por todas as instâncias) pode ser inicializada diretamente 
    species_count = 0

    # Construtor
    def __init__(self, name):
        # Variáveis de instância
        self.name = name       # público
        self._age = 0          # protegido por convenção
        self.__id = id(self)   # privado (mas você consegue acessar com name mangling)
        Animal.species_count += 1

    # Destrutor
    def __del__(self):
        Animal.species_count -= 1

    # Método regular
    def make_sound(self):
        pass  # Equivalente a um método abstrato/virtual (não implementável na classe base)

    # Método estático (não precisa de classe ou instância)
    @staticmethod
    def get_kingdom():
        return "Animalia"

    # Método de classe (recebe a classe como primeiro argumento)
    @classmethod
    def get_species_count(cls):
        return cls.species_count

    # Decorador de propriedade (getter)
    @property
    def age(self):
        return self._age

    # Decorador de propriedade (setter)
    @age.setter
    def age(self, value):
        if value >= 0:
            self._age = value

    # Métodos especiais (sobrecarga de operadores)
    def __str__(self):                # Como toString() - para string legível
        return f"Animal named {self.name}"

    def __repr__(self):               # Para debugging
        return f"Animal(name='{self.name}')"

    def __eq__(self, other):          # Operador de comparação ==
        return isinstance(other, Animal) and self.name == other.name

    def __len__(self):                # Função len()
        return self._age

    def __getitem__(self, key):       # Operador de acesso []
        if key == 'name':
            return self.name
        raise KeyError(key)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

#include 
#include 
#include 

class Animal {
public:
    static int species_count;

    Animal(const std::string& name) : name(name), _age(0), __id(++id_counter) { // construtor
        ++species_count;
    }

    ~Animal() {    // destrutor
        --species_count;
    }

    virtual void make_sound() = 0; // Método não implementável na classe base (virtual/abstrato)

    // getters:
    static std::string get_kingdom() {
        return "Animalia";
    }

    static int get_species_count() {
        return species_count;
    }

    int get_age() const {
        return _age;
    }

    // setter:
    void set_age(int age) {
        if (age >= 0) {
            _age = age;
        }
    }

    std::string to_string() const {
        return "Animal named " + name;
    }

    std::string repr() const {
        std::ostringstream oss;
        oss << "Animal(name="" << name << "", age=" << _age << ", id=" << __id << ")";
        return oss.str();
    }

    bool operator==(const Animal& other) const {
        return name == other.name;
    }

    // Sobrecarga do operador []
    std::string operator[](const std::string& key) const {
        if (key == "name") {
            return name;
        }
        throw std::out_of_range("Invalid key");
    }

    // Método isinstance
    template <typename T>
    bool isinstance() const {
        return dynamic_cast<const T*>(this) != nullptr;
    }

protected:
    std::string name;
    int _age;

private:
    int __id;
    static int id_counter;
};

// variáveis estáticas de classe são compartilhadas por todas as instâncias mas
// precisam ser inicializadas separadamente.
int Animal::species_count = 0;
int Animal::id_counter = 0;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

میراث

پایتون

class Dog(Animal):
    def __init__(self, name, breed):
        # Chama o construtor da classe pai
        super().__init__(name)
        self.breed = breed

    # Sobrescreve o método da classe pai
    def make_sound(self):
        return "Woof!"
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

class Dog : public Animal {
public:
    Dog(const std::string& name, const std::string& breed) : Animal(name), breed(breed) {}

    void make_sound() override {
        std::cout << "Woof!" << std::endl;
    }

private:
    std::string breed;
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ارث چندگانه

پایتون

class Pet:
    def is_vaccinated(self):
        return True

class DomesticDog(Dog, Pet):
    pass
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

class Pet {
public:
    bool is_vaccinated() const {
        return true;
    }
};

class DomesticDog : public Dog, public Pet {
public:
    DomesticDog(const std::string& name, const std::string& breed) : Dog(name, breed) {}
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

کلاس چکیده

پایتون

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

class Shape {
public:
    virtual ~Shape() {}
    virtual double area() const = 0;
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مثال استفاده

پایتون

if __name__ == "__main__":
    # Cria objetos
    dog = Dog("Rex", "Golden Retriever")

    # Acessa atributos
    print(dog.name)          # Público
    print(dog._age)         # Protegido (ainda acessível)
    # print(dog.__id)       # Isso falhará 
    print(dog._Animal__id)  # Isso funciona (acessando attribute privado com name mangling)

    # Propriedades
    dog.age = 5             # Usa setter automaticamente
    print(dog.age)          # Usa getter automaticamente

    # Métodos estáticos e de classe
    print(Animal.get_kingdom())
    print(Animal.get_species_count())

    # Verifica herança
    print(isinstance(dog, Animal))  # True
    print(issubclass(Dog, Animal)) # True

    # Métodos especiais em ação
    print(str(dog))        # Usa __str__
    print(repr(dog))       # Usa __repr__
    print(len(dog))        # Usa __len__
    print(dog['name'])     # Usa __getitem__
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

int main() {
    // Cria objetos
    Dog dog("Rex", "Golden Retriever");

    // Acessa atributos
    std::cout << dog.name << std::endl;          // Público
    std::cout << dog.get_age() << std::endl;     // Protegido (ainda acessível)
    // std::cout << dog.__id << std::endl;       // Isso falhará (privado)

    // Propriedades
    dog.set_age(5);             // Usa setter
    std::cout << dog.get_age() << std::endl;     // Usa getter

    // Métodos estáticos e de classe
    std::cout << Animal::get_kingdom() << std::endl;
    std::cout << Animal::get_species_count() << std::endl;

    // Equivalente aos "métodos especiais":

    // Verifica herança
    if (dog.isinstance<Animal>()) {
        std::cout << "dog é uma instância de Animal" << std::endl;
    }

    std::cout << dog.to_string() << std::endl;   // Usa to_string
    std::cout << dog.repr() << std::endl;        // Usa repr
    std::cout << dog["name"] << std::endl;       // Usa operador []
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تفاوت های کلیدی پایتون و C++98

  1. بدون کلمات کلیدی عمومی/خصوصی/محافظت شده (استفاده از قراردادهای نامگذاری)
  2. ارث چندگانه متفاوت است:
    • پایتون از ترتیب وضوح روش (MRO) با خطی سازی C3 استفاده می کند
    • بدون نیاز به وراثت مجازی مانند C++
    • super() به طور خودکار MRO را دنبال می کند
    • ترتیب کلاس های پایه در پایتون مهم است
    • شما می توانید دستور حل و فصل را با __mro__
  3. همه متدها به صورت پیش فرض مجازی هستند
  4. بدون نیاز به فایل های هدر
  5. هیچ تمایزی بین اشاره گرها / ارجاعات وجود ندارد
  6. بدون نیاز به مدیریت حافظه ( زباله جمع کن )
  7. همه چیز یک شی است (از جمله توابع)
  8. تایپ پویا به جای تایپ ایستا
  9. دکوراتورهای املاک به جای روش های گیر/ستر
  10. روش های خاص از قالب استفاده می کنند __name__ به جای کلمه کلیدی عملگر
  11. سینتکس بیشتر پایتونیک برای بارگذاری بیش از حد اپراتور (به عنوان مثال __eq__ در مقابل operator==)

استفاده کنید dir(object) برای دیدن تمام ویژگی ها و روش های یک شی، و help(object) برای مستندسازی

مشکل ارث بری الماس

مشکلات وراثت الماس در C++98

وراثت الماس زمانی اتفاق می افتد که یک کلاس از دو کلاس ارث می برد که به نوبه خود از یک کلاس پایه مشترک ارث می برند. این می تواند چندین مشکل ایجاد کند:

  1. ابهام: روش ها و ویژگی های کلاس پایه مشترک می توانند مبهم شوند.
  2. تکثیر داده ها: هر کلاس مشتق شده می تواند کپی خود را از اعضای کلاس پایه مشترک داشته باشد که منجر به تکرار داده ها می شود.

مثال وراثت الماس در C++98

class Animal {
public:
    Animal() {
        std::cout << "Animal constructor" << std::endl;
    }
    virtual void make_sound() {
        std::cout << "Some generic animal sound" << std::endl;
    }
};

class Pet : public Animal {
public:
    Pet() : Animal() {
        std::cout << "Pet constructor" << std::endl;
    }
    void make_sound() override {
        std::cout << "Pet sound" << std::endl;
    }
};

class WorkingAnimal : public Animal {
public:
    WorkingAnimal() : Animal() {
        std::cout << "WorkingAnimal constructor" << std::endl;
    }
    void make_sound() override {
        std::cout << "Working animal sound" << std::endl;
    }
};

class DomesticDog : public Pet, public WorkingAnimal {
public:
    DomesticDog() : Animal(), Pet(), WorkingAnimal() {
        std::cout << "DomesticDog constructor" << std::endl;
    }
    void make_sound() override {
        Pet::make_sound();  // Ou WorkingAnimal::make_sound(), dependendo do comportamento desejado
    }
};

int main() {
    DomesticDog dog;
    dog.make_sound();
    return 0;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

رفتار مورد انتظار

Animal constructor
Pet constructor
WorkingAnimal constructor
DomesticDog constructor
Pet sound
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مثال، DomesticDog گله از Pet ه WorkingAnimal، هر دو به ارث می برند Animal. این یک الماس موروثی ایجاد می کند. وراثت مجازی برای جلوگیری از تکرار و ابهام داده ها استفاده می شود.

چگونه پایتون به طور خودکار از ارث بری الماس جلوگیری می کند

پایتون از ترتیب وضوح روش (MRO) با خطی سازی C3 برای حل خودکار مسائل ارث بری الماس استفاده می کند. MRO هنگام جستجوی یک متد یا ویژگی، ترتیب بررسی کلاس ها را تعیین می کند.

مثال وراثت الماس در پایتون

class Animal:
    def make_sound(self):
        print("Some generic animal sound")

class Pet(Animal):
    def make_sound(self):
        print("Pet sound")

class WorkingAnimal(Animal):
    def make_sound(self):
        print("Working animal sound")

class DomesticDog(Pet, WorkingAnimal):
    pass

dog = DomesticDog()
dog.make_sound()
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

رفتار مورد انتظار

Pet sound
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مثال، پایتون به طور خودکار وراثت الماس را با استفاده از MRO حل می کند. شما می توانید MRO را با استفاده از ویژگی بررسی کنید __mro__:

print(DomesticDog.__mro__)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

MRO در پایتون این را تضمین می کند DomesticDog به درستی از Pet ه WorkingAnimal، و آن Animal قبل حل شود object. بنابراین، ترتیب اعلامیه بر MRO تأثیر می گذارد، اما خطی سازی C3 تضمین می کند که سلسله مراتب رعایت می شود.

توضیح:

  1. دستور اعلامیه: MRO با مشتق ترین کلاس شروع می شود و از ترتیبی که طبقات پایه اعلام می شوند پیروی می کند.
  2. خطی سازی C3: تضمین می کند که هر کلاس قبل از سوپرکلاس های خود ظاهر می شود و ترتیب وراثت حفظ می شود.

ساختارهای داده: پشته، صف و نقشه

پشته

پایتون

stack = [] # we could just use a list as a stack
stack.append(1)  # push
stack.append(2)
print(stack.pop())  # pop
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

#include  // we have to import the stack type
std::stack<int> stack;
stack.push(1);  // push
stack.push(2);
std::cout << stack.top() << std::endl;  // top
stack.pop();  // pop
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

صف

پایتون

from collections import deque
queue = deque()
queue.append(1)  # enqueue
queue.append(2)
print(queue.popleft())  # dequeue
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

#include 
std::queue<int> queue;
queue.push(1);  // enqueue
queue.push(2);
std::cout << queue.front() << std::endl;  // front
queue.pop();  // dequeue
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نقشه

پایتون

map = {}
map['key1'] = 'value1'
map['key2'] = 'value2'
print(map['key1'])
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

C++98

#include 
std::map<std::string, std::string> map;
map["key1"] = "value1";
map["key2"] = "value2";
std::cout << map["key1"] << std::endl;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا