Подтвердить что ты не робот

Печать всех экземпляров класса

С классом в Python, как определить функцию для печати каждого отдельного экземпляра класса в формате, определенном в функции?

4b9b3361

Ответ 1

В этом случае я вижу два варианта:

Сборщик мусора

import gc
for obj in gc.get_objects():
    if isinstance(obj, some_class):
        dome_something(obj)

У этого есть недостаток - быть очень медленным, когда у вас много объектов, но работает с типами, над которыми у вас нет контроля.

Используйте mixin и weakrefs

from collections import defaultdict
import weakref

class KeepRefs(object):
    __refs__ = defaultdict(list)
    def __init__(self):
        self.__refs__[self.__class__].append(weakref.ref(self))

    @classmethod
    def get_instances(cls):
        for inst_ref in cls.__refs__[cls]:
            inst = inst_ref()
            if inst is not None:
                yield inst

class X(KeepRefs):
    def __init__(self, name):
        super(X, self).__init__()
        self.name = name

x = X("x")
y = X("y")
for r in X.get_instances():
    print r.name
del y
for r in X.get_instances():
    print r.name

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

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

Изменить. Метод печати всех экземпляров в соответствии с определенным форматом остается в виде упражнения, но в основном это вариация на for -loops.

Ответ 2

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

import weakref

class A:
    instances = []
    def __init__(self, name=None):
        self.__class__.instances.append(weakref.proxy(self))
        self.name = name

a1 = A('a1')
a2 = A('a2')
a3 = A('a3')
a4 = A('a4')

for instance in A.instances:
    print(instance.name)

Ответ 3

Очень хороший и полезный код, но у него есть большая проблема: список всегда больше и его никогда не очищают, чтобы проверить его, просто добавьте print(len(cls.__refs__[cls])) в конце метода get_instances.

Вот исправление для метода get_instances:

__refs__ = defaultdict(list)

@classmethod
def get_instances(cls):
    refs = []
    for ref in cls.__refs__[cls]:
        instance = ref()
        if instance is not None:
            refs.append(ref)
            yield instance
    # print(len(refs))
    cls.__refs__[cls] = refs

или, альтернативно, это можно сделать с помощью WeakSet:

from weakref import WeakSet

__refs__ = defaultdict(WeakSet)

@classmethod
def get_instances(cls):
    return cls.__refs__[cls]

Ответ 4

Как и все другие языки OO, сохраняйте все экземпляры класса в какой-либо коллекции.

Вы можете попробовать такие вещи.

class MyClassFactory( object ):
    theWholeList= []
    def __call__( self, *args, **kw ):
         x= MyClass( *args, **kw )
         self.theWholeList.append( x )
         return x

Теперь вы можете сделать это.

object= MyClassFactory( args, ... )
print MyClassFactory.theWholeList

Ответ 5

Python не имеет эквивалента Smallktalk #allInstances, поскольку в архитектуре нет такой таблицы центральных объектов (хотя современные мелкие строки тоже не работают).

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

Ответ 6

Возможно, вы имеете в виду что-то вроде __str__:

object.__str__(self)

Вызывается встроенной функцией str() и оператором печати для вычисления "неформального" строкового представления объекта. Это отличается от repr() тем, что оно не должно быть допустимым выражением Python: вместо этого может использоваться более удобное или сжатое представление. Возвращаемое значение должно быть строковым объектом.

Тривиальный пример:

>>> class dummy(object):
...     def __init__(self):
...         pass
...     def __str__(self):
...         return "I am a dummy"
...     
>>> d1=dummy()
>>> d2=dummy()
>>> print d1,d2
I am a dummy I am a dummy
>>>

Ответ 7

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

В любом случае я бы решил это, написав класс factory, используя поддержку метакласса Python. Если у вас нет контроля над классом, вручную обновите __metaclass__ для отслеживаемого класса или модуля.

Подробнее см. http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html.

Ответ 8

Вам не нужно импортировать НИЧЕГО! Просто используйте "Я". Вот как ты это делаешь

class A:
    instances = []
    def __init__(self):
        self.__class__.instances.append(self)

    @classmethod
    def printInstances(cls):
        for instance in cls.instances:
            print(instance)
A.printInstances()

Это так просто. Нет импортированных модулей или библиотек