[python] как работать с self?

yroslavasako

Очень хочется переприсвоить self. Вроде как питон весьма гибкий и интроспективный/рефлексивный язык. Как можно определить метод класса, который подменяет self на нечто другое, фактически делая из одного объекта объект другого типа?

yroslavasako

есть функция id :: Object -> Pointer, но для неё я не нашёл обратной функции xXx :: Pointer -> Object (Pointer - это Int).
Из того, что нашлось быстро, можно использовать ctypes модуль, у него есть параметр передачи объекта byref(obj)

pilot

@

yroslavasako

@
разверни мысль.

SCIF32

а______

bleyman

Если тебе нужно поменять тип, менять следует self.__class__. Но НАФИГА это тебе?
Если ты хочешь подправить все ссылки на данный объект, чтобы они указывали на какой-нибудь другой объект, ну, ищи все ссылки (у gc был метод) и подправляй, чё. Или можешь использовать Pypy, у них есть настоящий become: http://codespeak.net/pypy/dist/pypy/doc/objspace-proxies.htm...
Только у меня почему-то ощущение, что ты сам не знаешь, чего хочешь!

yroslavasako

Только у меня почему-то ощущение, что ты сам не знаешь, чего хочешь!
чего хочу - знаю, только что выбрал неверный путь. С gc (поправить все старые ссылки на объект a ссылкой на объект b) идея провалилась. Попробовал код написать. Во-первых, легко ломается frame вычеслений, что делает экспериментирование невыносимым. Во-вторых, что делать с tuple, которые immutable или с frozenset? делать новый тапл и везде подставлять вместо старого и так в рекурсии?
Так что вот чего я хочу: чтобы self у класса хранился по ссылке. И его можно было бы подменять на лету, например превратить родителя в потомка. Наверное для этого достаточно написать декоратор класса, который бы обеспечил хранения данных по ссылке (list из одного элемента или как ещё можно?) и обеспечивал доступ к нему, переписав __setattr__, __getattr__,__getattribute__ - так что это будет моей следующей попыткой.
Как это правильно (для гугла) называется чего я хочу, и может быть уже где есть реализации?

psihodog

Так что вот чего я хочу: чтобы self у класса хранился по ссылке.
ну так это, вроде, не проблема... сделай ровно что ты говоришь: обращайся к self.self
если хочется косметики, то да, используй декораторы, метаклассы, что угодно...
но оно тебе точно надо?
превратить родителя в потомка
не очень понятно, насколько это логически правильно, но если ты знаешь, что делаешь,
то для конкретно этой цели, может лучше написать что-нть вроде
x.__class__ = Y

?

yroslavasako

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

yroslavasako

. Или можешь использовать Pypy, у них есть настоящий become: http://codespeak.net/pypy/dist/pypy/doc/objspace-proxies.htm...
практически вот этого и хочу. Оно есть под обычный питон?

bleyman

я пишу прокси. И хотелось бы, чтобы потомок создавался корректно
Ты какую-то фигню пишешь. Ты же пытаешься засунуть нужную функциональность в базовый класс и от него наследоваться, да? А зачем? Используй factory function и не парься, намного и проще, и удобней, и понятней получится.

yroslavasako

я хочу механизм проксирования, когда один объект можно представить разными способами. Например матрицы можно разбить на строчки, а можно на столбцы. Нужно чтобы можно было конвертировать из одного представления в другое на лету. Понятное дело, я привёл неполное описание, если существенно необходимо полное - придётся много набирать текста

bleyman

Ну так и конвертируй функцией или методом! Который возвращает прокси для объекта в новом представлении!
Зачем тебе незаметно, изподтишка менять представление сразу по всей программе? Жизнь кажется слишком пресной, скучной и благоустроенной, хочется острых ощущений, вот код работал себе с матрицей, а тут её хуяк — и транспонировало прям посреди операции, happy debugging?

yroslavasako

Я всё-таки был прав, у классических классов два уровня индирекции есть. Так что подменить его - плёвое дело

a.__dict__ = b.__dict__
a.__class__ = b.__class__

вот и всё. Метод подмены dict считается pythonic way, используется в паттерне borg. Не работает с неклассическими классами (у которых нет __dict__, таковые можно получить, описав __slots__ в секции описания класса, либо определив __prepare__ в описании метакласса так что нужно делать проверку и возвращать exception.
Пришлось заботать документацию по питону и несколько статей с developersworks и с прочих источников.
Одна тайна для меня осталась. Жутко интересно какой тип у __dict__ класса. type возвращает <class 'dict_proxy'>. Мне было весьма интересно, что это за зверь, и как можно явно объявить переменную такого класса у себя в коде. Но инфы в инете не нашёл. Разве что код исходный CPython читать
Оставить комментарий
Имя или ник:
Комментарий: