python 中的类的 Lambda 函数?

发布于 2024-07-09 23:52:53 字数 852 浏览 7 评论 0原文

一定有一种简单的方法可以做到这一点,但不知何故我可以解决它。 我描述我想要的最好的方法是类的 lambda 函数。 我有一个库需要一个类的未实例化版本作为参数来使用。 然后它实例化该类本身以进行处理。 问题是我希望能够动态创建该类的版本,以传递给库,但我不知道如何做到这一点,因为库需要一个未实例化的版本。 下面的代码描述了这个问题:

class Double:
    def run(self,x):
        return x*2

class Triple:
    def run(self,x):
        return x*3

class Multiply:
    def __init__(self,mult):
        self.mult = mult
    def run(self,x):
        return x*self.mult

class Library:
    def __init__(self,c):
        self.c = c()
    def Op(self,val):
        return self.c.run(val)

op1 = Double
op2 = Triple
#op3 = Multiply(5)

lib1 = Library(op1)
lib2 = Library(op2)
#lib3 = Library(op3)

print lib1.Op(2)
print lib2.Op(2)
#print lib3.Op(2)

我无法使用通用的 Multiply 类,因为我必须首先实例化它,这会破坏库“AttributeError:Multiply 实例没有 call 方法”。 在不更改 Library 类的情况下,有没有办法可以做到这一点?

There must be an easy way to do this, but somehow I can wrap my head around it. The best way I can describe what I want is a lambda function for a class. I have a library that expects as an argument an uninstantiated version of a class to work with. It then instantiates the class itself to work on. The problem is that I'd like to be able to dynamically create versions of the class, to pass to the library, but I can't figure out how to do it since the library expects an uninstantiated version. The code below describes the problem:

class Double:
    def run(self,x):
        return x*2

class Triple:
    def run(self,x):
        return x*3

class Multiply:
    def __init__(self,mult):
        self.mult = mult
    def run(self,x):
        return x*self.mult

class Library:
    def __init__(self,c):
        self.c = c()
    def Op(self,val):
        return self.c.run(val)

op1 = Double
op2 = Triple
#op3 = Multiply(5)

lib1 = Library(op1)
lib2 = Library(op2)
#lib3 = Library(op3)

print lib1.Op(2)
print lib2.Op(2)
#print lib3.Op(2)

I can't use the generic Multiply class, because I must instantiate it first which breaks the library "AttributeError: Multiply instance has no call method". Without changing the Library class, is there a way I can do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

遗忘曾经 2024-07-16 23:52:53

库是否真的指定它需要“未初始化版本”(即类引用)?

在我看来,图书馆实际上想要一个对象工厂。 在这种情况下,可以输入:

lib3 = Library(lambda: Multiply(5))

要了解 lambda 的工作原理,请考虑以下事项:

Multiply5 = lambda: Multiply(5)
assert Multiply5().run(3) == Multiply(5).run(3)

Does the library really specify that it wants an "uninitialized version" (i.e. a class reference)?

It looks to me as if the library actually wants an object factory. In that case, it's acceptable to type:

lib3 = Library(lambda: Multiply(5))

To understand how the lambda works, consider the following:

Multiply5 = lambda: Multiply(5)
assert Multiply5().run(3) == Multiply(5).run(3)
初相遇 2024-07-16 23:52:53

根本不需要 lambda。 lambda 只是定义函数并同时使用它的语法糖。 就像任何 lambda 调用都可以替换为显式 def 一样,我们可以通过创建满足您的需求的真实类并返回它来解决您的问题。

class Double:
    def run(self,x):
        return x*2

class Triple:
    def run(self,x):
        return x*3

def createMultiplier(n):
    class Multiply:
        def run(self,x):
            return x*n
    return Multiply

class Library:
    def __init__(self,c):
        self.c = c()
    def Op(self,val):
        return self.c.run(val)

op1 = Double
op2 = Triple
op3 = createMultiplier(5)

lib1 = Library(op1)
lib2 = Library(op2)
lib3 = Library(op3)

print lib1.Op(2)
print lib2.Op(2)
print lib3.Op(2)

There's no need for lambda at all. lambda is just syntatic sugar to define a function and use it at the same time. Just like any lambda call can be replaced with an explicit def, we can solve your problem by creating a real class that meets your needs and returning it.

class Double:
    def run(self,x):
        return x*2

class Triple:
    def run(self,x):
        return x*3

def createMultiplier(n):
    class Multiply:
        def run(self,x):
            return x*n
    return Multiply

class Library:
    def __init__(self,c):
        self.c = c()
    def Op(self,val):
        return self.c.run(val)

op1 = Double
op2 = Triple
op3 = createMultiplier(5)

lib1 = Library(op1)
lib2 = Library(op2)
lib3 = Library(op3)

print lib1.Op(2)
print lib2.Op(2)
print lib3.Op(2)
不打扰别人 2024-07-16 23:52:53

这是一种作弊行为,但您可以为 Multiply 类提供一个返回自身的 __call__ 方法:

class Multiply:
    def __init__(self,mult):
        self.mult = mult
    def __call__(self):
        return self
    def run(self,x):
        return x*self.mult

这样,当库调用 c() 时,它实际上会调用 c .__call__() 返回您想要的对象。

This is sort of cheating, but you could give your Multiply class a __call__ method that returns itself:

class Multiply:
    def __init__(self,mult):
        self.mult = mult
    def __call__(self):
        return self
    def run(self,x):
        return x*self.mult

That way when the library calls c() it actually calls c.__call__() which returns the object you want.

毁我热情 2024-07-16 23:52:53
def mult(x):
    def f():
        return Multiply(x)
    return f


op3 = mult(5)
lib3 = Library(op3)
print lib3.Op(2)
def mult(x):
    def f():
        return Multiply(x)
    return f


op3 = mult(5)
lib3 = Library(op3)
print lib3.Op(2)
羞稚 2024-07-16 23:52:53

如果我正确理解你的问题空间,你有一个通用接口,它接受 1 个参数,使用 Library 类调用它。 不幸的是,Library 并没有调用函数,而是假设该函数被包装在具有 run 方法的类中。

您当然可以以编程方式创建这些类。 类可以通过方法返回,并且由于闭包的概念,您应该能够将任何函数包装在满足您需求的类中。 类似的:

def make_op(f):
  class MyOp(object):
    def run(self, x):
      return f(x)
  return MyOp

op1 = make_op(lambda x: return x*2)
op2 = make_op(lambda x: return x*3)

def multiply_op(y):
    return make_op(lambda x: return x*y)

op3 = multiply_op(3)

lib1 = Library(op1)
lib2 = Library(op2)
lib3 = Library(op3)

print( lib1.Op(2) )
print( lib2.Op(2) )
print( lib3.Op(2) )

话虽如此,更改库以获取函数然后提供函数可能是更强大的方法。

If I understand your problem space correctly, you have a general interface that takes 1 argument which is called using the Library class. Unfortunately, rather than calling a function, Library assumes that the function is wrapped in a class with a run method.

You can certainly create these classes programatically. Classes may be returned by methods, and thanks to the concept of closures you should be able to wrap any function in a Class that meets your needs. Something like:

def make_op(f):
  class MyOp(object):
    def run(self, x):
      return f(x)
  return MyOp

op1 = make_op(lambda x: return x*2)
op2 = make_op(lambda x: return x*3)

def multiply_op(y):
    return make_op(lambda x: return x*y)

op3 = multiply_op(3)

lib1 = Library(op1)
lib2 = Library(op2)
lib3 = Library(op3)

print( lib1.Op(2) )
print( lib2.Op(2) )
print( lib3.Op(2) )

That being said, changing Library to take a function and then providing functions is probably the stronger way to do this.

我三岁 2024-07-16 23:52:53

由于 type 是 python 类对象的默认类,并且调用类会创建该类的新实例,因此使用正确的参数调用 type 将生成一个新类。

my_class = type("my_class", (object,), {"an_attribute": 1})

my_class 现在引用一个名为“my_class”的新类,它是 object 的子类,具有名为“an_attribute”的属性,其值为 1。因为方法也是只是指向函数对象的类属性,您也可以将它们添加到属性字典中:

{"an_attribute": 1, "a_method": lambda self: print("Hello")}

这就是它的工作原理。 我不建议这样做,除非你绝对需要这样做。 在 99% 的情况下,你不会。 请参阅 @Parker Coates 的回答,了解实现目标的干净方法。

Since type is the default class of a python class object, and calling a class creates a new instance of that class, calling type with the correct arguments will result in a new class.

my_class = type("my_class", (object,), {"an_attribute": 1})

my_class now refers to a new class named "my_class", which is a subclass of object, with an attribute called "an_attribute", whose value is 1. Since methods are also just class attributes pointing to a function object, you can add them to the dictionary of attributes as well:

{"an_attribute": 1, "a_method": lambda self: print("Hello")}

This is how it works. I do not recommend doing it this way, unless you absolutely need to. In 99% of all cases, you don't. Refer to @Parker Coates' answer for the clean way to achieve your goal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文