클래스의 모든 인스턴스 인쇄
Python의 클래스를 사용하여 함수에 정의 된 형식으로 클래스의 모든 단일 인스턴스를 인쇄하는 함수를 어떻게 정의합니까?
이 경우 두 가지 옵션이 표시됩니다.
가비지 수집기
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
이 경우 모든 참조는 목록에 약한 참조로 저장됩니다. 많은 인스턴스를 자주 생성하고 삭제하는 경우 반복 후 weakref 목록을 정리해야합니다. 그렇지 않으면 많은 엉망이 될 것입니다.
이 경우 또 다른 문제는 기본 클래스 생성자를 호출해야한다는 것입니다. 을 재정의 할 수도 __new__
있지만 __new__
인스턴스화에는 첫 번째 기본 클래스 의 메서드 만 사용됩니다. 이것은 또한 사용자가 제어하는 유형에서만 작동합니다.
편집 : 특정 형식에 따라 모든 인스턴스를 인쇄하는 방법은 연습으로 남겨져 있지만 기본적으로 for
루프 의 변형 일뿐입니다.
클래스에 정적 목록을 만들고 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)
Very nice and useful code, but it has a big problem: list is always bigger and it is never cleaned-up, to test it just add print(len(cls.__refs__[cls]))
at the end of the get_instances
method.
Here a fix for the get_instances
method:
__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
or alternatively it could be done using WeakSet:
from weakref import WeakSet
__refs__ = defaultdict(WeakSet)
@classmethod
def get_instances(cls):
return cls.__refs__[cls]
Same as almost all other OO languages, keep all instances of the class in a collection of some kind.
You can try this kind of thing.
class MyClassFactory( object ):
theWholeList= []
def __call__( self, *args, **kw ):
x= MyClass( *args, **kw )
self.theWholeList.append( x )
return x
Now you can do this.
object= MyClassFactory( args, ... )
print MyClassFactory.theWholeList
Python doesn't have an equivalent to Smallktalk's #allInstances as the architecture doesn't have this type of central object table (although modern smalltalks don't really work like that either).
As the other poster says, you have to explicitly manage a collection. His suggestion of a factory method that maintains a registry is a perfectly reasonable way to do it. You may wish to do something with weak references so you don't have to explicitly keep track of object disposal.
It's not clear if you need to print all class instances at once or when they're initialized, nor if you're talking about a class you have control over vs a class in a 3rd party library.
In any case, I would solve this by writing a class factory using Python metaclass support. If you don't have control over the class, manually update the __metaclass__
for the class or module you're tracking.
See http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html for more information.
You don't need to import ANYTHING! Just use "self". Here's how you do this
class A:
instances = []
def __init__(self):
self.__class__.instances.append(self)
@classmethod
def printInstances(cls):
for instance in cls.instances:
print(instance)
A.printInstances()
It's this simple. No modules or libraries imported
ReferenceURL : https://stackoverflow.com/questions/328851/printing-all-instances-of-a-class
'Nice programing' 카테고리의 다른 글
IE 브라우저의 텍스트 필드에서 Selenium WebDriver 입력이 매우 느림 (0) | 2021.01.10 |
---|---|
'Microsoft.Build.Tasks.v14.0.dll'을 찾을 수 없기 때문에 Visual Studio 2015에서 빌드 할 수 없습니다. (0) | 2021.01.10 |
XSL "포함"지시문이 있습니까? (0) | 2021.01.10 |
일반 배열을 포함하는 객체의 GetHashCode 재정의 (0) | 2021.01.10 |
VIM 스크립팅에 대한 좋은 가이드? (0) | 2021.01.10 |