Присвоение идентификаторов экземплярам класса (Pythonic) - PullRequest
0 голосов
/ 07 июня 2010

Я хочу, чтобы каждый экземпляр некоторого класса имел уникальный целочисленный идентификатор в зависимости от порядка их создания, начиная с (скажем) 0. В Java я мог бы сделать это с помощью статической переменной класса.Я знаю, что могу подражать такому же поведению с Python, но какой самый «питонический» способ сделать это?

Спасибо

Ответы [ 3 ]

3 голосов
/ 07 июня 2010

Следующий подход был бы относительно pythonic (для моего субъективного суждения о pythonic - явный, но краткий):

class CounterExample(object):

    instances_created = 0

    def __init__(self):
        CounterExample.instances_created += 1

    def __del__(self):
        """ If you want to track the current number of instances
            you can add a hook in __del__. Otherwise use
            __init__ and just count up.
        """
        CounterExample.instances_created -= 1

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

Пример метакласса: http://www.youtube.com/watch?v=E_kZDvwofHY#t=0h56m10s.

1 голос
/ 07 июня 2010

ответ the-myyn хорош - я думаю, что объект класса - идеальное место для хранения счетчика.Однако обратите внимание, что, как написано, это не потокобезопасно.Так что оберните его в метод класса, который использует блокировку:

import threading

class CounterExample(object):

    _next_id = 0
    _id_lock = threading.RLock()

    @classmethod
    def _new_id(cls):
        with cls._id_lock:
            new_id = cls._next_id
            cls._next_id += 1
        return new_id

    def __init__(self):
        self.id = self._new_id()

def test():
    def make_some(n=1000):
        for i in range(n):
            c = CounterExample()
            print "Thread %s; %s has id %i" % (threading.current_thread(), c, c.id)

    for i in range(10):
        newthread = threading.Thread(target=make_some)
        newthread.start()

test()

Это запускает 10 потоков, каждый из которых создает 1000 экземпляров.Если вы запустите его без кода блокировки, вы, скорее всего, получите последний идентификатор ниже 9999, что свидетельствует о состоянии гонки.

0 голосов
/ 07 июня 2010

Наверное, хороший вопрос: когда и как они создаются? Если вы просто создаете определенное количество из них в один момент времени, используйте диапазон в цикле for.

class A:
    def __init__ (self, id):
        self.id = id
        //do other stuff

class_list = []
for i in xrange(10):
    class_list.append(A(i))

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

РЕДАКТИРОВАТЬ: О, также, если сомневаетесь, «импортировать это» всегда может помочь вам на правильном пути для выяснения, что является «pythonic»;)

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