каждый объект python класса имеет одинаковое значение атрибута после создания

У меня два класса BaseNode и BaseEdge что я могу использовать connect метод соединения буксировочных узлов через ребро в этих классах.

код

вот мой BaseNode:

class BaseNode:
  def __init__(self,edges=[],value=None,edges_limit=math.inf):
    self.edges = edges
    self.value = value
    self.limit = edges_limit
    self.edge_class = BaseEdge
    self.adjs = []

  def get_adjacents(self):
    if not self.edges:
        return []
    for edge in self.edges :
        self.adjs.append(edge.n2)
    return self.adjs

  def get_edges(self):
    return self.edges

  def connect(self,other):
    """
    connect two nodes by connecting an edge between them
    """
    if not isinstance(other,self.__class__):
        raise ValueError(f'Node should be type of {self.__class__.__name__}')
    if len(self.edges) == self.limit :
        raise MaximumEdgeReached(f'maximum edge reached the limit is {self.limit} ')
    e = BaseEdge()
    e.set_nodes(self,other)
    self.edges.append(e)

и BaseEdge класс:

class BaseEdge:
  def __init__(self):
    self.n1 = None
    self.n2 = None
    self.node_class = BaseNode

  def get_nodes(self):
    return (self.n1,self.n2,)

  def set_nodes(self,n1,n2):
    a = isinstance(n1,self.node_class)
    b = isinstance(n2,self.node_class)

    if not a and b :
        raise ValueError(f'nodes of this edge should be {self.node_class}')
    self.n1 = n1
    self.n2 = n2

  def connect(self,n1=None,n2=None):
    if not self.n1 and self.n2 :
        self.set_nodes(n1,n2)
    self.n1.edges.append(self)
    self.n2.edges.append(self)

что я пробовал?

я попытался связать кивки от обоих BaseNode и BaseEdgeчтобы увидеть результаты. узлы должны иметь одинаковые ребра, но возникли 2 проблемы:

  1. edges атрибут n1 и n2 которые являются первым узлом и вторым узлом, имеют 2 экземпляра eкакой край! но edges должен иметь 1 экземпляр BaseEdge
  2. когда я создаю новые объекты BaseNode, то edgesатрибут имеет одинаковое значение для них!! .
    >>> n1 = BaseNode()
    >>> n2 = BaseNode()
    >>> e = BaseEdge()
    >>> e.set_nodes(n1,n2)
    >>> e.connect()
    >>> n2.edges
    [<__main__.BaseEdge object at 0x0000000003282BA8>, <__main__.BaseEdge object at 0x0000000003282BA8>]
    >>> n1.edges
    [<__main__.BaseEdge object at 0x0000000003282BA8>, <__main__.BaseEdge object at 0x0000000003282BA8>]
    >>> n3 = BaseNode() #initializing new oject
    >>> n3.edges
    [<__main__.BaseEdge object at 0x0000000003282BA8>, <__main__.BaseEdge object at 0x0000000003282BA8>]

Примечание: когда я использую connect метод BaseNodeкласс. у него такая же проблема.

BaseNodeclass просто действует как моногосударственный класс. и этого не должно быть! пожалуйста, помогите мне решить эту проблему.

1 ответ

Решение

Это старая проблема с изменяемым аргументом по умолчанию - чтобы не вводить все это снова, я предлагаю вам прочитать это: https://florimond.dev/blog/articles/2018/08/python-mutable-defaults-are-the-source-of-all-evil/

По сути, вместо определения функции как таковой..

def my_function(input_list=[]):
   input_list.append(2)
   ...

Вы должны определить это как

def my_function(input_list=None):
   if input_list is None:
      input_list = []

   input_list.append(2)
   ...

Это предотвращает аргумент по умолчанию [] от повторного использования в последующих вызовах функции.

Другие вопросы по тегам