Могу ли я присвоить объект класса переменной, если я уже вызвал его?Python 3 - PullRequest
0 голосов
/ 27 ноября 2018
class myClass:
    pass

myClass()

Использование myClass() создает объект типа myClass.Как я могу назначить именно этот объект переменной после того, как просто вызвал его так?Потому что, если я добавлю a = myClass() после вызова myClass (), будет создан другой объект, и a будет указывать на этот другой объект.

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

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

import gc

class myClass:
    pass

myClass() 
print( [o for o,t in globals().items() if isinstance(t, myClass)], [o for o in gc.get_objects() if isinstance(o, myClass)] )

a = myClass()
print( [o for o,t in globals().items() if isinstance(t, myClass)], [o for o in gc.get_objects() if isinstance(o, myClass)] )
del a

gc.disable() # even disabling the garbage collector will not make a difference
myClass()
print( [o for o,t in globals().items() if isinstance(t, myClass)], [o for o in gc.get_objects() if isinstance(o, myClass)] )

Вывод:

[] []
['a'] [<__main__.myClass object at 0x00000000046026D8>]
[] []

Однако вы можете заставить класс самостоятельно отслеживать ссылки:

import gc

class myClass:
    ref = []
    def __init__(self):
        myClass.ref.append(self)

myClass()
print( [o for o,t in globals().items() if isinstance(t, myClass)], [o for o in gc.get_objects() if isinstance(o, myClass)] )

a = myClass()
print( [o for o,t in globals().items() if isinstance(t, myClass)], [o for o in gc.get_objects() if isinstance(o, myClass)] )
del a

gc.collect() # force garbage collection
print( [o for o,t in globals().items() if isinstance(t, myClass)], [o for o in gc.get_objects() if isinstance(o, myClass)] )

Вывод:

[] [<__main__.myClass object at 0x00000000048226D8>]
['a'] [<__main__.myClass object at 0x00000000048226D8>, <__main__.myClass object at 0x0000000004890860>]
[] [<__main__.myClass object at 0x0000000004890860>, <__main__.myClass object at 0x00000000048226D8>]

Примечание: таким образом, сборщик мусора никогда не удаляет экземпляры этого класса, даже если переменная удаляется, до тех пор, покапоскольку класс хранит ссылку на экземпляр!

0 голосов
/ 27 ноября 2018
class MyClass:
    instances = []

    def __init__(self, name: str):
        self.name = name

        MyClass.instances.append(self)

    def printName(self):
        print("My name is " + self.name)

    def setName(self, name: str):
        self.name = name


a = MyClass("Joshua")

a.printName()   # Outputs 'My name is Joshua'

b = a

b.printName() # Outputs 'My name is Joshua'

b.setName("DeepSpace")

a.printName()   # Outputs 'My name is DeepSpace'
b.printName()   # Outputs 'My name is DeepSpace'

MyClass.instances[0].printName()    # Outputs 'My name is DeepSpace'

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

0 голосов
/ 27 ноября 2018

Сделать что-то подобное невозможно из-за сборки мусора CPython:

myClass()
a = lastObjectCreated()

Но не имеет прецедента и невозможен на 100% (по крайней мере, с CPython), потому что объект уничтожается сразу после егосозданный смысл, ни одна переменная не указывает на него (ни одна переменная не имеет ссылки на класс).

Слабая ссылка - это ссылка, которая не препятствует удалению объекта.При этом мы можем наблюдать удаление объекта, например, так:

class myClass:
    pass

import weakref

def catch_deletion(object):
    print('Object was deleted')

weakref.ref(myClass(), catch_deletion)
#Output: Object was deleted

Это доказывает, что он действительно исчез.

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