簡體   English   中英

跟蹤創建了多少類對象

[英]keep track of how many class objects are created

我想創建多個對象,並且我希望每個對象都跟蹤它的創建順序,所以第一個對象的 id 為 1,第二個 id 為 2,依此類推。

class Something:
    id=0
    def __init__(self):
        Something.id+=1

目前,我設法跟蹤實例但沒有順序。 所以

something1=Something()
something2=Something()

如果我調用 id,兩者都返回 2

在這種情況下,兩個類都返回 2 的 id 的原因是因為您正在遞增類變量而不是特定於實例的變量。

您可以改為使用兩者來獲取正確的 id,即以下內容:

class Something:
    id=0
    def __init__(self):
        Something.id+=1
        self.id = Something.id
        
something1=Something()
something2=Something()

print(something1.id, something2.id)

(這打印1 2 )。 在這種情況下,Something.id(類變量)的值也是 2。

基本上你需要的是一個類來計算自己創建的實例的數量,它可以用來設置實例id屬性的值。 計數本身可以通過將內置的next()函數應用於itertools.count()迭代器對象來完成。

此外,由於您可能希望將此功能添加到多個類,因此在元類中實現實例計數將是有意義的,因為這樣做可以輕松地重用它。 使用元類還可以確保子類 - 即class SomethingElse(Something): - 每個都有自己單獨的實例計數器(而不是它們都共享基類中的一個,因為它會在大多數其他答案中到目前為止)。

這是我的建議:

from itertools import count


class InstanceCounterMeta(type):
    """Metaclass to maintain an instance count."""

    def __init__(cls, name, bases, attrs):
        super().__init__(name, bases, attrs)
        cls._instance_count = count(start=1)


class Something(metaclass=InstanceCounterMeta):
    def __init__(self):
        self.id = next(self._instance_count)


something1 = Something()
something2 = Something()

print(something1.id)  # -> 1
print(something2.id)  # -> 2

只需創建一個非靜態的id成員:

class Something:
    id = 0

    def __init__(self):
        Something.id += 1;
        self.id = Something.id


something1 = Something()
something2 = Something()

print(something1.id) # Prints 1
print(something2.id) # Prints 2

如果Something的目標不僅僅是跟蹤實例,您可以將此任務分開並使其獨立於它。 globals()內置函數是一個字典,其中包含“標識符對象”的鍵對。 它是一本字典,因此尊重插入順序。

請注意,它返回調用時的狀態,因此如果某些對象被刪除,它們將不會出現在globals()中。

class A: pass

a1 = A()
a3 = A()
a2 = A()

# amount of instances
len(tuple(obj for obj in globals().values() if isinstance(obj, A)))
# 3

# object identifiers at this state of the program
(tuple(k for k, v in globals().items() if isinstance(v, A)))
# ('a1', 'a3', 'a2')

# delete an object
del a1
# new state
(tuple(k for k, v in globals().items() if isinstance(v, A)))
('a3', 'a2')

編輯 - 實現為類方法

class A:

    @classmethod
    def instance_counter(cls):
        n = len(tuple(obj for obj in globals().values() if isinstance(obj, cls)))
        objs = ', '.join(tuple(k for k, v in globals().items() if isinstance(v, cls)))
        print(f'"{n}" instances of {cls.__name__} are in use: "{objs}"')

a1 = A()
a3 = A()
a2 = A()
A.instance_counter()
#"3" instances of A are in use: "a1, a3, a2"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM