繁体   English   中英

将方法作为变量分配给对象

[英]Assigning a method to an object as a variable

我希望对象在它们的例程中调用某个方法(在变量中分配的特定方法)。 我设法用 dict 来做到这一点,我还设法通过在创建对象后分配变量来做到这一点。 哪种方式更好? 还有其他更清洁的方法吗?

第一种工作方式(字典):

class Foo:
    def __init__(self, name, funcin) -> None:
        self.name = name
        self.func = {
            'bear': self.bear,
            'boar': self.boar,
        }[funcin]
    
    def routine(self):
        print('fluff')
        self.func()

    def bear(self):
        print(f'I, {self.name}, am a bear and I like honey.')
    
    def boar(self):
        print(f'I, {self.name}, am a boar and I like fruits.')

bob = Foo('bob', 'bear')
mark = Foo('mark', 'boar')

bob.routine()
mark.routine()

第二种工作方式(另一行分配):

class Foo:
    def __init__(self, name) -> None:
        self.name = name
    
    def routine(self):
        print('fluff')
        self.func()

    def bear(self):
        print(f'I, {self.name}, am a bear and I like honey.')
    
    def boar(self):
        print(f'I, {self.name}, am a boar and I like fruits.')
    
Kona = Foo('Kona')
Kona.func = Kona.bear
John = Foo('John')
John.func = John.boar

Kona.routine()
John.routine()

无效的方法:

# NameError: name 'bear' is not defined
class Foo:
    def __init__(self, name, funcin) -> None:
        self.name = name
        self.func = self.funcin
    def bear(self):
        print(f'I, {self.name}, am a bear and I like honey.')
bob = Foo('bob', bear)
bob.func()

# NameError: name 'self' is not defined
class Foo:
    def __init__(self, name, funcin) -> None:
        self.name = name
        self.func = funcin
    def bear(self):
        print(f'I, {self.name}, am a bear and I like honey.')
bob = Foo('bob', self.bear)
bob.func()

# NameError: name 'Kim' is not defined
class Foo:
    def __init__(self, name, funcin) -> None:
        self.name = name
        self.func = funcin
    def bear(self):
        print(f'I, {self.name}, am a bear and I like honey.')
Kim = Foo('Kim', Kim.bear)
Kim.func()   

# TypeError: Foo.bear() missing 1 required positional argument: 'self'
class Foo:
    def __init__(self, name, funcin) -> None:
        self.name = name
        self.func = funcin
    def bear(self):
        print(f'I, {self.name}, am a bear and I like honey.')
bob = Foo('bob', Foo.bear)
bob.func()

类的方法就像它们在 dict 中一样通过类的__dict__属性可用。 因此,在您提出的第一个解决方案中,您还可以像这样定义self.func

self.func = Foo.__dict__[funcin].__get__(self)

所以使用__dict__[funcin]我们从类对象中检索方法,使用__get__我们得到一个具有正确self绑定的函数。

为了使它更通用,以便您不必提及Foo

self.func = self.__class__.__dict__[funcin].__get__(self)

一个常见的解决方案是类继承。 从抽象基类到 mixin 有多种选择,但这里是一个简单的开始

class Foo:
    def __init__(self, name) -> None:
        self.name = name
        
    def func(self):
        raise NotImplementedError
    
    def routine(self):
        print('fluff')
        self.func()

class Bear(Foo):
    
    def func(self):
        print(f'I, {self.name}, am a bear and I like honey.')
    
class Boar(Foo):
    
    def func(self):
        print(f'I, {self.name}, am a boar and I like fruits.')

bob = Bear('bob')
mark = Boar('mark')

bob.routine()
mark.routine()

您可以使用 getattr():

class Foo:
    def __init__(self, name, funcin) -> None:
        self.name = name
        self.func = getattr(self,funcin)
    
    def routine(self):
        print('fluff')
        self.func()

    def bear(self):
        print(f'I, {self.name}, am a bear and I like honey.')
    
    def boar(self):
        print(f'I, {self.name}, am a boar and I like fruits.')

如果您不需要执行额外的(常见)绒毛,您可以简单地分配self.routine = getattr(self,funcin)甚至不定义routine() 函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM