Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 20, 2018 17:49:16

lordwader
Зарегистрирован: 2018-10-20
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Создание методов класса на лету

Всем привет! Задача следующая: Реализовать простой класс с несколькими методами. При вызове метода которого не существует он должен быть создан на лету и вызван. В качестве результата вызова - имя метода.
Вот мой код:

 class Foo(object):
    def sum(self, arg = 0):
        print(arg + 5)
 
    def minus(self, arg = 0):
        print(10 - arg)
 
    def __getattribute__( self, name ):
        self.cur_name = name
        return self
    
    def __call__( self, *args, **kwargs ):
        func_name = super().__getattribute__( "cur_name" )
        if func_name in dir(Foo):
            return self.func_name()
        print(func_name)
 
f = Foo()
f.sum()
f.minus()
f.bar()
f.ber()
f.bar()
f.bar_1()
f.sum()
__call__ и __getattribute__ перехватывают все методы и не вызывают minus и sum. Подскажите пожалуйста, где я ошибся в коде.

Офлайн

#2 Окт. 20, 2018 22:10:43

rami
Зарегистрирован: 2018-01-08
Сообщения: 281
Репутация: +  72  -
Профиль   Отправить e-mail  

Создание методов класса на лету

Исправьте на:

 def __getattr__(self, name):

Офлайн

#3 Окт. 21, 2018 07:16:57

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Создание методов класса на лету

lordwader
Подскажите пожалуйста, где я ошибся в коде.
Везде. Добавление нового метода это манипуляции с классом а не с объектом.



Отредактировано doza_and (Окт. 21, 2018 07:21:36)

Офлайн

#4 Окт. 21, 2018 11:19:47

Papa_Svin
Зарегистрирован: 2018-09-17
Сообщения: 138
Репутация: +  1  -
Профиль   Отправить e-mail  

Создание методов класса на лету

doza_and
Добавление нового метода это манипуляции с классом а не с объектом.
В питоне нет проблем добавить метод в объект. Надо чтобы автор уточнил, в какую именно сущность он желает добавлять методы

Офлайн

#5 Окт. 21, 2018 17:07:01

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Создание методов класса на лету

lordwader
Реализовать простой класс с несколькими методами. При вызове метода которого не существует он должен быть создан на лету и вызван. В качестве результата вызова - имя метода.
это должен быть метод класаа или инстанса?
lordwader
__call__ и __getattribute__ перехватывают все методы и не вызывают minus и sum. Подскажите пожалуйста, где я ошибся в коде.
во первых __call__ вообще не учавствует там никак, он сработает только если сделать f().
__getattribute__ я бы не трогал, лучше переопредели __getattr__ тогда он будет перехватывать только непределенные атрибуты.
както так, в конкретной реализации оно добавляет методы в инстанс, легко переделывается чтобы добавляло методы в класс.
 class Foo(object):
    def sum(self, arg = 0):
        print('summm!!!')
    def minus(self, arg = 0):
        print('minus!!!')
    def make_method(self, name):
        print('creating func:', name)
        def _method():
            print(name)
        _method.__name__ = name
        setattr(self, name, _method)
    def __getattr__(self, key):
        try:
            res = super().__getattribute__(key)
        except AttributeError:
            self.make_method(key)
            res = self.__getattribute__(key)
        return res
f = Foo()
f.sum()
f.minus()
f.bar()
f.ber()
f.bar()
f.bar_1()
f.sum()
print(f.__dict__)
вывод:
>>> 
>>>
summm!!!
minus!!!
creating func: bar
bar
creating func: ber
ber
bar
creating func: bar_1
bar_1
summm!!!
{'ber': <function ber at 0x02EE6540>, 'bar_1': <function bar_1 at 0x02EE6618>, 'bar': <function bar at 0x02EE64B0>}
>>>
>>>



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Окт. 21, 2018 17:43:18)

Офлайн

#6 Окт. 22, 2018 20:18:42

lordwader
Зарегистрирован: 2018-10-20
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Создание методов класса на лету

Спасибо за подсказки и советы. В общем реализовал так:

 def bind(self, as_name):
        setattr(self, as_name, (lambda pop: print(as_name)).__get__(self, self.__class__))
        
def __getattr__(self, name):
    try:
        func_name = super().__getattribute__(name)
    except AttributeError:
        self.bind(name)
        func_name = self.__getattribute__(name)
    return func_name
Теперь пытаюсь понять, как это переделать, чтобы добавляло методы в класс а не в инстанс.

Офлайн

#7 Окт. 23, 2018 00:03:20

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2849
Репутация: +  186  -
Профиль   Отправить e-mail  

Создание методов класса на лету

Зачем такие сложности?

 >>> class A(object):
...     def __getattr__(self, attr):
...         metod = lambda: attr
...         setattr(self, attr, metod)
...         return metod
>>> a = A()
>>> a.aaa()
'aaa'
>>> a.bbb()
'bbb'
<function <lambda> at 0x7efff6be72a8>
Тут конечно не методы, а атрибуты. Если хочешь именно настоящих методов, то их нужно добавлять в класс как собственно уже сказали.
 >>> metod = lambda self: "attr"
>>> setattr(A, "attr", metod)
>>> A.attr(a)
'attr'
>>> A.attr
<unbound method A.<lambda>>



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version