我可能会错过一些愚蠢的东西,或者我只是想通过钢墙走过而不是四处走走。基本上我创建了turtle
类,我在不同的脚本中使用它来绘制L系统。我想我可以在 turtle
类之外创建一个函数,它将接受:
turtle
- 来自我的turtle
类turtle
类但是这一切都在试图将方法传递给函数时崩溃了 - 我认为它没有看到方法,因为它是在类中定义的。为了简化我创建的基本示例,它在同一个地方失败了:
class Person():
def __init__(self, age):
self.age = age
def birthday(self):
self.age += 1
def foo(person, method):
person.method()
jane = Person(20)
foo(jane, birthday)
#Traceback (most recent call last):
# File "passmethod.py", line 14, in <module>
# foo(jane, birthday)
#NameError: name 'birthday' is not defined
那是:
Person
类实例中唯一的变量是age
,唯一的方法是birthday
将年龄提高1。jane
是Person
类实例,初始化为20岁foo
我试图在她的birthday
方法
birthday
方法并崩溃所以,我的问题是(是):
感谢那些快速而美好的答案!自然遵循的附加问题 - 是否有任何优先选择?我猜,那是
__getattribute__
和getattr
几乎相同,但对于第一个,继承可能是必要的。jane.birthday
或Person.birthday
之间,我看不出在这种情况下有任何重大差异,但一般来说,能够调用不同Person
实例的方法,例如在foo
函数中创建。答案 0 :(得分:2)
这是工作代码:
class Person():
def __init__(self, age):
self.age = age
def birthday(self):
self.age += 1
def foo(person, method):
getattr(person, method)()
测试:
>>>
>>> jane = Person(20)
>>> foo(jane, 'birthday')
>>> jane.age
21
>>>
答案 1 :(得分:1)
嗯,有办法做到这一点。
第一种方法:只传递绑定到特定对象的方法:
def foo(person, method):
method() # calls jane.birthday()
jane = Person(20)
foo(jane, jane.birthday)
第二种方式:传递一个类方法并将其应用于特定对象:
def foo(person, method):
method(person) # calls Person.birthday(jane), which is the same thing
jane = Person(20)
foo(jane, Person.birthday)
答案 2 :(得分:1)
您可以使用__getattribute__
方法(继承自object
):
class Person(object):
def __init__(self, age):
self.age = age
def birthday(self):
self.age += 1
def foo(person, method):
person.__getattribute__(method)()
jane = Person(20)
foo(jane, "birthday")
答案 3 :(得分:1)
正如我在评论中建议的那样,您可以对Turtle
进行细分,以添加规则跟踪方法。为了演示一个简单的例子:
class InstructableTurtle(Turtle):
def follow_instructions(self, instructions):
for instruction in instructions:
if instruction == "MOVE_LEFT":
self.move_left()
...
但您也可以将rules
作为新实例的附加参数提供:
def __init__(self, ..., rules): # '...' represents args to base Turtle
super().__init__(...) # or 'super(InstructableTurtle, self)' on Python 2.x
self.rules = rules
举个例子:
>>> class Turtle():
def __init__(self, name):
self.name = name
def move_left(self):
print("{0.name} is moving left...".format(self))
>>> class InstructableTurtle(Turtle):
def __init__(self, name, rules):
super().__init__(name)
self.rules = rules
def follow_instruction(self, instruction):
self.rules[instruction](self)
>>> tommy = InstructableTurtle("Tommy", {"LEFT": Turtle.move_left})
>>> tommy.follow_instruction("LEFT")
Tommy is moving left...