使用面向对象的方法将函数作为参数传递的等效方法是什么

2024-04-27 20:31:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我用python编写了一个程序,其中包含一个类,该类将函数作为__init__方法的参数。此函数作为属性存储,并在类中的不同位置使用。传入的函数可以是多种多样的,传入一个键然后从一组预定义的函数中进行选择将不会提供相同程度的灵活性。在

现在,如果一长串这样的问题不酷,我道歉,但是。。。在

  • 在函数不是第一类对象的语言中,它们是实现这一点的标准方法吗?在
  • 在这方面,像smalltalk或objective-C中的块算函数吗?在
  • 在这些语言中,块是最好的方法吗?在
  • 如果没有街区怎么办?在
  • 你能在运行时添加一个新方法吗?在
  • 在哪种语言中这是可能的(而且容易)?在
  • 或者用一个执行所需操作的方法创建一个对象会更好吗?在
  • 如果我想传递很多函数,我会创建很多单例对象吗?在
  • 这会被认为是一种更面向对象的方法吗?在
  • 有人会考虑在python中使用函数作为第一类对象吗?在

Tags: 对象方法函数程序语言参数标准属性
3条回答

您可以使用strategy pattern。基本上你传入一个具有已知接口但行为不同的对象。这就像传递函数,但它被一个对象包住了。在

我只想回答你的一些问题。在

正如他们在Scheme社区中所说的,“对象是穷人的闭包”(闭包是头等函数)。块通常只是闭包的语法糖。对于没有闭包的语言,存在各种解决方案。在

一个常见的解决方法是使用运算符重载:C++有一个函数对象的概念,它定义了成员{{CD1>}(“操作符函数调用”)。Python有一个类似的重载机制,您可以在其中定义__call__

class Greeter(object):
    def __init__(self, who):
         self.who = who

    def __call__(self):
         print("Hello, %s!" % who)

hello = Greeter("world")
hello()

是的,您可以考虑在Python中使用它,而不是在对象中存储函数,因为函数不能是pickled。在

在没有运算符重载的语言中,您将看到类似Guava的^{}接口。在

我不明白你说的“相当于。。。使用面向对象的方法”。在Python中,既然函数(如您所说)是一级对象,那么将函数作为参数传递不是“面向对象”的吗?在

a standard way to achieve this in a language where functions aren't first class objects?

我想说的是,只有在某种程度上,函数的标准方式不能成为一级对象。在

<>在C++中,通常创建另一类,通常称为函子泛函类EEE>,定义了{{CD1>}的过载,允许实例像语法一样使用函数。但是,通常也可以使用普通的旧函数指针。指针和指向函数都不是一级对象,但接口足够丰富。在

这与通过模板实现的“即席多态”很好地吻合;您可以编写实际上不关心传递类实例还是函数指针的函数。在

类似地,在Python中,通过为类定义一个__call__方法,可以使对象注册为callable。在

Do blocks, like in smalltalk or objective-C, count as functions in this respect?

我会说是的。至少lambda和Python中的函数一样重要,实际上更重要的是因为它们没有像Python的lambda那样被削弱。在

Would blocks be the best way to do this in those languages?

这取决于你需要什么。在

Could you add a new method at runtime? In which languages would this be possible (and easy)?

提供对自己的编译器进行自省和运行时访问的语言。Python符合条件。在

然而,到目前为止,关于这个问题还没有任何东西表明需要跳过这样的圈套。当然,对于一个新的类,有些语言比其他语言有更多需要的样板。在

Or would it be better to create an object with a single method that performs the desired operation?

这是相当标准的。在

What if I wanted to pass lots of functions, would I create lots of singleton objects?

你这样说好像你可能会无意中创建了一个以上的类实例,如果你不写大量的样板来阻止自己这样做。在

Would this be considered a more object oriented approach?

“我不能理解”这个词。这并不意味着“创造大量的对象”。在

^{8磅}$

不需要一个类能做的和函数不能做的额外的事情。有了duck类型,你到底为什么要费心呢?在

相关问题 更多 >