将方法作为变量分配给对象
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()
class 的方法可以通过 class 的 __dict__
属性在字典中使用。因此,在您提出的第一个解决方案中,您还可以这样定义 self.func
:
self.func = Foo.__dict__[funcin].__get__(self)
所以使用 __dict__[funcin]
我们从 class 对象中检索方法,使用 __get__
我们得到一个具有正确 self
绑定的函数。
让它更通用,这样你就不用再提了 Foo
:
self.func = self.__class__.__dict__[funcin].__get__(self)
一个常见的解决方案是class 继承。从 abstract base classes 到 mixins 有多种选择,但这里是一个简单的开始
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() 函数。
我希望对象在它们的例程中调用某个方法(在变量中分配的特定方法)。我设法用字典做到了,我还设法通过在对象创建后分配变量来做到这一点。哪种方式更好?还有其他更清洁的方法吗?
第一种可行的方法(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()
class 的方法可以通过 class 的 __dict__
属性在字典中使用。因此,在您提出的第一个解决方案中,您还可以这样定义 self.func
:
self.func = Foo.__dict__[funcin].__get__(self)
所以使用 __dict__[funcin]
我们从 class 对象中检索方法,使用 __get__
我们得到一个具有正确 self
绑定的函数。
让它更通用,这样你就不用再提了 Foo
:
self.func = self.__class__.__dict__[funcin].__get__(self)
一个常见的解决方案是class 继承。从 abstract base classes 到 mixins 有多种选择,但这里是一个简单的开始
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() 函数。