简体   繁体   English

防止函数成为Python 2中的实例方法

[英]Prevent a function from becoming an instancemethod in Python 2

I'm writing some code that works in Python 3 but not Python 2. 我正在编写一些适用于Python 3但不适用于Python 2的代码。

foo = lambda x: x + "stuff"

class MyClass(ParentClass):
    bar = foo

    def mymethod(self):
        return self.bar(self._private_stuff)

I would want it to simply print the private stuff, but if I try to run mymethod, I get: 我希望它只是打印私人的东西,但如果我尝试运行mymethod,我得到:

TypeError: unbound method <lambda>() must be called with MyClass instance as first argument (got str instance instead)

Of course, the above is not the actual code, but a simplification of the real thing. 当然,上面不是实际的代码,而是真实的简化。 I wanted to do it like this because I need to pass along private information that I don't want to expose the final user to ie anybody that extends my classes. 我想这样做是因为我需要传递我不想将最终用户公开的私人信息,即扩展我的类的任何人。 But in Python 2, the global level lambda (or any plain function) become an instancemethod , which is unwanted in this case! 但是在Python 2中,全局级lambda(或任何普通函数)成为一种instancemethod ,在这种情况下这是不需要的!

What do you recommend me to make this piece of code portable? 您建议我将这段代码移植到什么位置?

Simplest: 最简单的:

class MyClass(ParentClass):
    bar = staticmethod(foo)

with the rest of your code staying the same. 其余代码保持不变。 While staticmethod is most often used as a "decorator", there is no requirement to do so (thus, no requirement for a further level of indirection to have bar be a decorated method calling foo ). 虽然staticmethod最常用作“装饰器”,但没有要求这样做(因此,不需要进一步的间接级别来使bar成为调用foo的装饰方法)。

I would go with Alex Martelli's suggestion. 我会选择Alex Martelli的建议。 Just for the record, though, (I wrote this answer before seeing Alex Martelli's beautiful answer) you can also do the following in Python 2.7 and 3.x (note especially the documentation links I have provided, so that you understand what is going on): 但是,仅仅为了记录,(我在看到Alex Martelli的漂亮答案之前写了这个答案)你也可以在Python 2.7和3.x中做到以下几点(特别注意我提供的文档链接,以便你了解发生了什么) ):

You can use a static method , which will not expect an implicit first argument. 您可以使用静态方法 ,它不会期望隐含的第一个参数。 Note that lambda expressions cannot take statements , so you will not be able to use the print statement in your lambda function in 2.x. 请注意, lambda表达式不能使用语句 ,因此您将无法在2.x中的lambda函数中使用print语句。

foo = lambda x: x            # note that you cannot use print here in 2.x

class MyClass(object):

    @staticmethod            # use a static method
    def bar(x):
        return foo(x)        # or simply print(foo(x))

    def mymethod(self):
        return self.bar(1)

>>> m = MyClass()
>>> m.mymethod()
1

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

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