Автоинкрементные идентификаторы для экземпляров классов - PullRequest
2 голосов
/ 30 ноября 2011

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

Кроме того, я рассмотрел ответы на этот вопрос без особой удачи, поэтому, пожалуйста, не рассматривайте это как дубликат этого вопроса

Проблема :

У меня есть график (G = (V, E)). В какой-то момент в моем алгоритме мне нужно превратить это в гиперграф (в некотором смысле), «свернув» несколько узлов (скажем, v_1, v_2, ..., v_n) в один узел (скажем, v). В контексте проблемы это означает, что мне нужно изменить ребра в E так, чтобы любое ребро e между любым из v_1, v_2, v_n и любым другим узлом u в V было изменено так, чтобы e теперь между u и v.

Чтобы понять, что теперь может существовать несколько различных ребер между любой парой узлов, мне нужно сделать уникальный идентификатор для каждого ребра. Я попытался сделать это с помощью и идентификатора, который в настоящее время я не могу правильно реализовать.

Это то, что я пробовал :

class Edge:
    _ID = 0
    def __init__(self, u, v, w, c,f=0):
        self.id = Edge._ID 
        Edge._ID += 1
        self.src = u
        self.dest = v
        self.weight = w
        self.capacity = c
        self.flow = f

Однако, когда я пытаюсь создать новое ребро, я получаю следующую ошибку:

>>> e = Edge(1,3,5,10,0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "UnsplittableFlow.py", line 14, in __init__
    self.id = Edge._ID; Edge._ID += 1
UnboundLocalError: local variable '_ID' referenced before assignment

EDIT

С предложениями некоторых ответов я смог исправить ошибку времени инстанцирования. Тем не менее, еще одна ошибка сохраняется. Вот мой код и ошибки:

class Edge:
    _ID = 0
    def __init__(self, u, v, w, c,f=0):
        self.id = self._ID; self._ID += 1
        self.src = u
        self.dest = v
        self.weight = w
        self.capacity = c
        self.flow = f

Ошибка:

>>> e = Edge(1,3,5,10,0)
>>> e.id
0
>>> Edge._ID
0

>>> f = Edge(2,3,5,10,0)
>>> f.id
0
>>> Edge._ID
0

Буду признателен за любую помощь

Спасибо

Ответы [ 4 ]

4 голосов
/ 30 ноября 2011

Ваш отредактированный код обрабатывает _ID, как если бы это была переменная экземпляра, а не переменная класса. Основываясь на ответе Мэтта Джойнера, я думаю, что вы имеете в виду:

class Edge:
    _ID = 0
    def __init__(self, u, v, w, c,f=0):
        self.id = self._ID; self.__class__._ID += 1
        self.src = u
        self.dest = v
        self.weight = w
        self.capacity = c
        self.flow = f

Когда я запускаю ваши примеры с этим определением Edge, я получаю:

>>> e = Edge(1,3,5,10,0)
>>> e.id
0
>>> Edge._ID
1
>>> f = Edge(2,3,5,10,0)
>>> f.id
1
>>> Edge._ID
2

Какой желаемый результат. Тем не менее, другие отмечают, что ваш оригинальный код работает для них, так же, как этот код работает для меня, поэтому я подозреваю, что настоящая проблема где-то еще в вашем коде.

2 голосов
/ 30 ноября 2011

Перед созданием любого Edge вы можете явно установить переменную класса равной 0 следующим образом:

Edge._ID = 0
e = Edge(1,3,5,10,0)
f = Edge(2,3,4,5,0)

И идентификаторы будут установлены правильно.

2 голосов
/ 30 ноября 2011

Вы по-прежнему можете использовать self, чтобы войти в _ID.

self.id = self._ID 
self.__class__._ID += 1

Если вы используете CPython, вы можете иметь идентификатор ленивого человека:

class Edge(object):
    @property
    def id(self): return id(self)
1 голос
/ 30 июня 2012

В то время как другие предлагаемые ответы - это ответы на заданный вопрос (именно поэтому я не принимаю тот, который я изначально принял), правильный способ сделать это - использовать itertools.count следующим образом:

class Edge:
    _ID = itertools.count()
def __init__(self, u, v, w, c,f=0):
    self.id = self._ID.next()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...