Автоматические идентификаторы для экземпляров класса

StackOverflow https://stackoverflow.com/questions/8319910

Вопрос

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

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

Проблема:

У меня есть график (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

РЕДАКТИРОВАТЬ:

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

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

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

Спасибо

Это было полезно?

Решение

Вы все еще можете использовать self чтобы получить _ID.

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

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

class Edge(object):
    @property
    def id(self): return id(self)

Другие советы

Ваш отредактированный код обращается _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

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

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

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

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

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

class Edge:
    _ID = itertools.count()
def __init__(self, u, v, w, c,f=0):
    self.id = self._ID.next()
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top