Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 20, 2009 00:07:29

ikostia
От:
Зарегистрирован: 2009-11-19
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

self - присваивание

Здравствуйте!
Давайте сделаем вот так:

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 не работает.
Собственно, вопрос состоит в следующем: можно ли смоделировать такую функциональность каким-то образом? То есть, чтобы в методе объекта переназначать указатель на этот же объект. В принципе, можно написать конструктор копирования и вызывать его, но это создает дополнительные расходы по производительности и тогда будет не указатель переназначен, а создан другой такой же объект.

З.Ы. Простите, если вопрос глуп:)



Офлайн

#2 Ноя. 20, 2009 04:46:34

crchemist
От:
Зарегистрирован: 2008-07-09
Сообщения: 379
Репутация: +  0  -
Профиль   Отправить e-mail  

self - присваивание

ні; не можна

змінна “a” в коді є вказівником на екземпляр класу; відповідно в методі self = t нічо не робить зі змінною “a”. вона і далі вказує на той самий обєкт



Отредактировано (Ноя. 20, 2009 04:48:48)

Офлайн

#3 Ноя. 20, 2009 05:02:28

crchemist
От:
Зарегистрирован: 2008-07-09
Сообщения: 379
Репутация: +  0  -
Профиль   Отправить e-mail  

self - присваивание

По суті то називається проксі; ось кусок коду який робить те що тобі потрібно; присвоєння працювати не буде бо треба ще перекрити __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]$



Офлайн

#4 Ноя. 20, 2009 14:06:54

ikostia
От:
Зарегистрирован: 2009-11-19
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

self - присваивание

Дуже дякую.
Спробую розібратися в коді.
Ще одне питання, якщо можна.

crchemist
змінна “a” в коді є вказівником на екземпляр класу; відповідно в методі self = t нічо не робить зі змінною “a”
А self не є “альясом” для a? Якщо ні, то чи не могли б ви пояснити, що є по суті self…



Офлайн

#5 Ноя. 20, 2009 18:22:09

Ferroman
От:
Зарегистрирован: 2006-11-16
Сообщения: 2759
Репутация: +  1  -
Профиль   Отправить e-mail  

self - присваивание

self по суті - вказівник на сам екземпляр, не на його властивість а саме на об’єкт. На момент використання його в методі, він уже існує і проініціалізований, а отже запис self=a не має сенсу - обєкт не може сам себе переініцалізувати.
Селф використовується для доступу до методів і властивостей об’єкта в середині самого об’єкту.

Офлайн

#6 Ноя. 21, 2009 00:50:01

ikostia
От:
Зарегистрирован: 2009-11-19
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

self - присваивание

Ще одне питання, якщо можна.
Чому у

__getattribute__(self, '_A__other_instance')
ім'я атрибуту саме _A__other_instance, який принцип додавання префіксу _A?
І де про це можна почитати (україно-, російсько-, англомовні ресурси)? Бажано лінк не на книжку, а більш-менш на главу…



Офлайн

#7 Ноя. 21, 2009 06:26:41

dimabest
От:
Зарегистрирован: 2009-02-12
Сообщения: 253
Репутация: +  0  -
Профиль   Отправить e-mail  

self - присваивание

ikostia

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



Офлайн

#8 Ноя. 21, 2009 12:16:46

ikostia
От:
Зарегистрирован: 2009-11-19
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

self - присваивание

С русским - все нормально, я понимаю его.

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

def turn_to_reversed(self):
r = self.reversed()
self = r
Соответственно, оно не заработало и мне стало интересно, как такое вообще делается.

З.Ы. Я прекрасно понимаю, что можно написать конструктор копирования, мне просто стало интересно, как сделать это именно моим неудавшимся способом. Спасибо ребятам, объяснили. Вчера почитал еще о прокси-шаблоне проэктирования - очень полезная вещь, насколько я понимаю. Пользовался не раз, а отдельно читать не приходилось.



Отредактировано (Ноя. 21, 2009 12:26:16)

Офлайн

#9 Ноя. 22, 2009 12:40:08

crchemist
От:
Зарегистрирован: 2008-07-09
Сообщения: 379
Репутация: +  0  -
Профиль   Отправить e-mail  

self - присваивание

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__']
>>>



Отредактировано (Ноя. 22, 2009 12:49:35)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version