Найти - Пользователи
Полная версия: self - присваивание
Начало » Python для новичков » self - присваивание
1
ikostia
Здравствуйте!
Давайте сделаем вот так:
class a:
def __init__(self,v):
self.val = v

def m(self):
t = a(1)
self = t

def p(self):
print self.val
Если теперь написать:
q = a(2)
a.p()
то получим, очевидно, 2.

Если же написать:
q = a(2)
q.m()
q.p()
то получим те же 2. То есть, строка self = t не работает.
Собственно, вопрос состоит в следующем: можно ли смоделировать такую функциональность каким-то образом? То есть, чтобы в методе объекта переназначать указатель на этот же объект. В принципе, можно написать конструктор копирования и вызывать его, но это создает дополнительные расходы по производительности и тогда будет не указатель переназначен, а создан другой такой же объект.

З.Ы. Простите, если вопрос глуп:)
crchemist
ні; не можна

змінна “a” в коді є вказівником на екземпляр класу; відповідно в методі self = t нічо не робить зі змінною “a”. вона і далі вказує на той самий обєкт
crchemist
По суті то називається проксі; ось кусок коду який робить те що тобі потрібно; присвоєння працювати не буде бо треба ще перекрити __setattr__
[crchemist@localhost tmp]$ cat main.py
class A(object):
obj_getattr = object.__getattribute__

__other_instance = None

def __getattribute__(self, k):
if object.__getattribute__(self, '_A__other_instance'):
return getattr(object.__getattribute__(self, '_A__other_instance'), k)
return object.__getattribute__(self, k)

def __init__(self, v):
self.val = v

def m(self):
t = A(1)
self.__other_instance = t

def p(self):
print self.val

q = A(2)
q.p()

print '*' * 80

q = A(2)
q.m()
q.p()

[crchemist@localhost tmp]$ python main.py
2
********************************************************************************
1
[crchemist@localhost tmp]$
ikostia
Дуже дякую.
Спробую розібратися в коді.
Ще одне питання, якщо можна.
crchemist
змінна “a” в коді є вказівником на екземпляр класу; відповідно в методі self = t нічо не робить зі змінною “a”
А self не є “альясом” для a? Якщо ні, то чи не могли б ви пояснити, що є по суті self…
Ferroman
self по суті - вказівник на сам екземпляр, не на його властивість а саме на об’єкт. На момент використання його в методі, він уже існує і проініціалізований, а отже запис self=a не має сенсу - обєкт не може сам себе переініцалізувати.
Селф використовується для доступу до методів і властивостей об’єкта в середині самого об’єкту.
ikostia
Ще одне питання, якщо можна.
Чому у
__getattribute__(self, '_A__other_instance')
ім'я атрибуту саме _A__other_instance, який принцип додавання префіксу _A?
І де про це можна почитати (україно-, російсько-, англомовні ресурси)? Бажано лінк не на книжку, а більш-менш на главу…
dimabest
ikostia

Что не получается? Зачем понадобилось переназначать self?
Начинать надо с проблемы, а не хитро-мудрой попытки решить непонятно что
ikostia
С русским - все нормально, я понимаю его.

Проблемы как таковой не было. Просто я написал вот так - и оно не заработало, мне стало интересно, почему и можно ли сделать так, чтобы заработало.
Первоначально цель достаточно прозаична - класс матрицы, у которого есть метод, возвращающий экземпляр этого же класса - обратную матрицу, метод reversed(). И я, не подумав, хотел написать еще и метод turn_to_reversed() - превращающий данную матрицу в обратную. Ну и хотел его написать следующим образом:
def turn_to_reversed(self):
r = self.reversed()
self = r
Соответственно, оно не заработало и мне стало интересно, как такое вообще делается.

З.Ы. Я прекрасно понимаю, что можно написать конструктор копирования, мне просто стало интересно, как сделать это именно моим неудавшимся способом. Спасибо ребятам, объяснили. Вчера почитал еще о прокси-шаблоне проэктирования - очень полезная вещь, насколько я понимаю. Пользовался не раз, а отдельно читать не приходилось.
crchemist
dimabest
Начинать надо с проблемы, а не хитро-мудрой попытки решить непонятно что
То не хитро-мудрьона спроба;
ikostia
Вчера почитал еще о прокси-шаблоне проэктирования - очень полезная вещь, насколько я понимаю.
реалізація для пітона http://pypi.python.org/pypi/zope.proxy/3.4.2 написаний на сішці, дуже швидкий; залежить здається тільки від zope.interface. Застосування проксів можна подивитись в пакеті zope.security. В zope так безпека реалізована; Обєкти при підніманні з БД огортаються в проксі і на ті проксі навішуються різні дозволи на методи; після роботи з обєктом - він чистий витягується з проксі і зберігається назад в бд;
ikostia
Чому у
__getattribute__(self, '_A__other_instance')
ім'я атрибуту саме _A__other_instance, який принцип додавання префіксу _A?
Просто в пітоні так криво реалізовані приватні атрбибути(ті що починаютьсяз __ ); ну і щоб їх не було видно до них додають префікс _ClassName. Це стосується тільки атрибутів класу; ось приклад коду:
>>> class A(object):
... __some_attr = 'some attr'
...
>>> A.__some_attr
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'A' has no attribute '__some_attr'
>>> A._A__some_attr
'some attr'
>>> a = A()
>>> a.__some_attr
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute '__some_attr'
>>> a.__some_attr2 = 10
>>> a.__some_attr2
10
>>> a.__dict__.keys()
['__some_attr2']
>>> A.__dict__.keys()
['__dict__', '__module__', '__weakref__', '_A__some_attr', '__doc__']
>>>
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB