Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 16, 2012 09:34:41

duh386
От:
Зарегистрирован: 2012-01-16
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Одинаковые имена классов

Добрый день.
Начал работать с системой openErp, написанной на питоне. Там довольно часто используется схема наследования такого вида:

class Classname(osv.osv)
_name='Classname'
_inherit='Classname'
......
При этом osv.osv - это какой-то базовый класс (пока не важно), свойства _name и _inherit тоже какие-то служебные, сложно разобраться как они применяются при наследовании (и применяются ли вообще), но это пока тоже не важно. Дело в том, что класс с именем Classname уже существует, он тоже унаследован от osv.osv, имеет какие-то свойства/методы. Что происходит, если я объявляю класс с уже существующим именем?
Ошибку при этом интерпретатор не выдает (как в PHP например). Мои мысли на этот счет: возможно к методам/свойствам существующего класса добавляюся методы/свойства свежеобъявленного. Но вероятнее всего, что старый класс уничтожается и заменяется на новый, но при этом свойства/методы старого класса где-то каким-то образом сохраняются (возможно в новом классе - получается аналог мысли 1) - вероятно что при этом роль играют объявленные свойства _name и _inherit. Реально ли это сделать средствами питона? Какие еще возможны варианты?
Насколько я понимаю питон, тут вообще все переменные(и не только) - классы, и соответственно любую переменную/класс можно переопределить, т.е. возможно это просто аналог переопределения переменной? Но тогда каким образом можно сохранить старые свойства класса?



Отредактировано (Янв. 16, 2012 09:37:07)

Офлайн

#2 Янв. 16, 2012 13:09:11

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

Одинаковые имена классов

duh386
Но тогда каким образом можно сохранить старые свойства класса?
почитать про наследование



Офлайн

#3 Янв. 16, 2012 20:18:47

duh386
От:
Зарегистрирован: 2012-01-16
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Одинаковые имена классов

Сорри, не нашел инфы о наследовании, кроме стандартного способа: “ Class(Parentclass):… ”. Киньте ссылкой плз.



Офлайн

#4 Янв. 21, 2012 09:01:57

duh386
От:
Зарегистрирован: 2012-01-16
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Одинаковые имена классов

Может кто-нибудь может набросать пару строк кода с таким функционалом, хотя бы примерно, чтобы я понял идею.



Офлайн

#5 Янв. 21, 2012 09:34:11

Piton23
От:
Зарегистрирован: 2011-10-17
Сообщения: 139
Репутация: +  5  -
Профиль   Отправить e-mail  

Одинаковые имена классов

Офлайн

#6 Янв. 21, 2012 14:15:06

yrttyr
От:
Зарегистрирован: 2011-09-06
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Одинаковые имена классов

duh386
Может кто-нибудь может набросать пару строк кода с таким функционалом, хотя бы примерно, чтобы я понял идею.
А что он конкретно делает, объединяет методы двух объявленных классов в одном?



Офлайн

#7 Янв. 21, 2012 17:03:23

duh386
От:
Зарегистрирован: 2012-01-16
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Одинаковые имена классов

Piton23
Хм, и в какой по счету ссылке я могу найти интересующие меня примеры? Вы уверены что читали вопрос?

yrttyr
Да. Есть родительский класс. Есть унаследованный класс. Затем от родительского класса наследуется еще один, с таким же именем, как и первый унаследованный. Судя по всему методы обоих унаследованных объединяются. Это вообще реально?



Отредактировано (Янв. 21, 2012 17:04:29)

Офлайн

#8 Янв. 21, 2012 17:14:51

yrttyr
От:
Зарегистрирован: 2011-09-06
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Одинаковые имена классов

Да реально. С помощью метаклассов, например. Могу написать, если нужно.



Офлайн

#9 Янв. 21, 2012 17:56:11

Piton23
От:
Зарегистрирован: 2011-10-17
Сообщения: 139
Репутация: +  5  -
Профиль   Отправить e-mail  

Одинаковые имена классов

duh386
Что происходит, если я объявляю класс с уже существующим именем?
Возьмем к примеру:

class main():
_name = "main"
_my = "no change"


class child1(main):
_name = "child1"
def out(self):
print "call out " + self._name


o1 = child1()
print o1._name # out: child1
print o1.out() # out: call out child1

class child1(main):
_name = "child2"
# Затирается старый дочерний класс

o2 = child1()
print o2._name # out: child2
print o2.out() # AttributeError, естественно класс же затерт и его (метода) не существует
# Попытаемся обратится к методу старого child1
print o1._name # out: child1
print o1.out() # А здесь нет ошибки т.к. данный объект создавался до переопределения класса

# Затираем объект новым классом
o1 = child1()
print o1._name # out: child2
print o1.out() # AttributeError Все правильно данного метода нет в новой реализации
duh386
Но вероятнее всего, что старый класс уничтожается и заменяется на новый, но при этом свойства/методы старого класса где-то каким-то образом сохраняются
Почти. Правильно что уничтожается что видно из примера, а то что свойства и методы каким-то образом сохраняются, с чего вы взяли? они тоже уничтожаются. Тут важно когда, т.е. в какой момент создан был экземпляр/объект класса. Если создан до второго объявления дочернего, то данный экземпляр будет вести себя согласно старо-объявленному классу. Если после переопределения то согласно переопределенному. Никакие свойства не сохраняются и методы. Можно ж открыть IDLE и поэкспериментировать и почитать немного теории.

duh386
Но тогда каким образом можно сохранить старые свойства класса?
Я вообще не понимаю зачем вам пере затирать существующий класс. Это плохая практика. Если уж так жесткая в этом необходимость то к примеру если у вас первый дочерний класс имеет свойства, которые надо сохранить, то храните не в этом дочернем классе а выше в родительском, т.е. в свойствах osv.osv. И потом пере затирайте дочерние классы хоть 10 раз а ваши свойства останутся. Но так я сомневаюсь что кто то в здравом уме делает :)

Отредактировано (Янв. 21, 2012 18:14:05)

Офлайн

#10 Янв. 21, 2012 18:28:26

yrttyr
От:
Зарегистрирован: 2011-09-06
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Одинаковые имена классов

Для 2.7

#!/usr/bin/env python
# -*- coding: utf-8 -*-

class UnionMeta(type):
_dict = dict()

def __new__(meta, classname, bases, classdict):
if classname in meta._dict:
keep_cls = meta._dict[classname]
for key, value in classdict.items():
setattr(keep_cls, key, value)
return keep_cls
else:
inst = type.__new__(meta, classname, bases, classdict)
meta._dict[classname] = inst
return inst

class Union(object):
__metaclass__ = UnionMeta

# Тестируем
class A(Union):
def meth_a(self):
print 'A'

class A(Union):
def meth_a2(self):
print 'A2'

a = A()
a.meth_a()
a.meth_a2()



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version