Ошибка типа объекта в методе класса в Python - PullRequest
0 голосов
/ 06 июня 2019

У меня есть код-

from statistics import mean
from random import choice
from random import sample

import networkx as nx


class MyGraph(nx.Graph):
    def __init__(self, num_nodes, target_deg, target_wght, max_wght=5):
        super().__init__()
        self.num_nodes = num_nodes
        self.target_deg = target_deg
        self.target_wght = target_wght
        self.max_wght = max_wght
        self.add_nodes_from(range(self.num_nodes))
        while self.avg_deg() < self.target_deg:
            n1, n2 = sample(self.nodes(), 2)
            self.add_edge(n1, n2, weight=1)
        while self.avg_wght() < self.target_wght:
            n1, n2 = choice(list(self.edges()))
            if self[n1][n2]['weight'] < self.max_wght:
                self[n1][n2]['weight'] += 1

    def avg_deg(self):
        return self.number_of_edges() * 2 / self.num_nodes

    def avg_wght(self):
        wghts = []
        for i in range(self.num_nodes):
            for j in range(i + 1, self.num_nodes):
                try:
                    wghts.append(self[i][j]['weight'])
                except KeyError:
                    pass
        return mean(wghts)




a=MyGraph(100,4,5)

print(type(a))      

output-

<class '__main__.MyGraph'>

Я определил объект как nx.graph, тогда почему объект MyGraph отличается от типа networkx?В моем определении класса я упомянул объект nx.Graph, поэтому, когда я вызываю класс, он должен возвращать мне объект типа networkx.

1 Ответ

1 голос
/ 06 июня 2019

С этим кодом:

class MyGraph(nx.Graph):

Вы создали новый класс, который унаследован от nx.Graph.Это новый класс, а не nx.Graph, поэтому при создании экземпляра этого класса в его type записывается имя вашего нового класса.Это нормальное поведение не только для Python, но и почти для каждого языка с поддержкой ООП.

Унаследованные классы могут использовать все не приватные методы родительских классов:

ВыполнениеОпределение производного класса происходит так же, как и для базового класса.Когда объект класса создан, базовый класс запоминается.Это используется для разрешения ссылок на атрибуты: если запрошенный атрибут не найден в классе, поиск переходит к поиску в базовом классе.Это правило применяется рекурсивно, если сам базовый класс является производным от некоторого другого класса.

Производные классы могут переопределять методы своих базовых классов.Поскольку у методов нет специальных привилегий при вызове других методов того же объекта, метод базового класса, который вызывает другой метод, определенный в том же базовом классе, может в конечном итоге вызвать метод производного класса, который переопределяет его.(Для программистов на C ++: все методы в Python являются фактически виртуальными.)

В действительности переопределяющий метод в производном классе может захотеть расширить, а не просто заменить метод базового класса с тем же именем.Существует простой способ прямого вызова метода базового класса: просто вызовите BaseClassName.methodname (self, arguments).Это иногда полезно и для клиентов.(Обратите внимание, что это работает только в том случае, если базовый класс доступен как BaseClassName в глобальной области видимости.)

Для этого была создана вся концепция наследования.Я рекомендую вам прочитать статью в Википедии о наследовании , чтобы полностью понять ее, потому что это основная концепция для большинства популярных языков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...