Lambda没有在python3.6中创建实例方法

2024-06-10 22:48:56 发布

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

我正在尝试创建名称基于类实例的特定属性的方法。我的代码类似于:

class myClass:
    info_to_be_accessed = {
        'infoA': 14,
        'infoB': 21,
        'infoC': False,
        'infoD': 'spam'
    }

    def create_methods(self):
        for info in self.info_to_be_accessed:
            setattr(self, info, lambda self: self.info_to_be_accessed.get(info, None))
        return self

c = myClass().create_methods()
print(c.infoA())

我原以为c.infoA()是一个实例方法,但结果证明它是一个静态方法,在调用时没有获得self参数。输出引发TypeError

Traceback (most recent call last):
  File "test.py", line 15, in <module>
    print(c.infoA())
TypeError: <lambda>() missing 1 required positional argument: 'self'

预期产量:

14

编辑:回答@chepner。老实说,我不确定这是最好的处理方法,但我的基本问题是,我处理的数据超出了我的数据库/我自己的代码。我正在从一个我无法控制的数据库中检索信息,因此可以通过我的代码对其进行分析。基本上,我真正的代码类有一个dataframe,其中包含有关复杂SQL查询结果的信息以及绘制有关它的图表的能力,但有时我想过滤dataframe以绘制它,有时我想绘制整个内容。我不是真的在分析字典,而是创建方法来过滤这个数据帧。问题是,我用这个查询分析的(外部)对象有一个特定属性可以是的固定值,但是如果这个外部数据库将来发生更改,我不想创建额外的代码来覆盖添加到那里的新值。在分析这些数据时,使用方法而不是参数对我来说更方便,但这不是用于生产的代码,只是我在CLI中使用的代码。这就是为什么对每个可以传递的值有单独的方法对我来说很方便的原因。你知道吗


Tags: to数据实例方法代码selfinfo数据库
1条回答
网友
1楼 · 发布于 2024-06-10 22:48:56

(有点)回复wim的评论:

我自己还没有遇到一个好的用例,但是您可以设置 任意函数作为任意实例的方法。它的款式好吗?在大多数情况下可能有更好的方法。但你可以,我来示范。你知道吗


您只是在设置一个属性,它恰好是实例上的一个函数。你知道吗

函数是(非数据)descriptors,您可以使用它们的__get__方法来修复第一个参数。你知道吗

演示:

>>> class myClass: 
...:     def __repr__(self): # nicer output for demo 
...:         return '<myClass object>' 
...:     def create_method_on_instance(self, name, function): 
...:         setattr(self, name, function.__get__(self))                                                               
>>>                                                                                                                    
>>> m1 = myClass()                                                                                                     
>>> m2 = myClass()                                                                                                     
>>> m1.create_method_on_instance('foo', lambda self, x, y: print(self, x + y))                                           
>>> m2.create_method_on_instance('foo', lambda self, x, y: print(self, x - y))                                           
>>>                                                                                                             
>>> m1.foo(3, 4)                                                                                                       
<myClass object> 7
>>> m2.foo(3, 4)                                                                                                 
<myClass object> -1

我不能在这里重复描述HowToFunctions and Methods section的所有内容,但它分解如下:

通过点表示法访问实例上的函数属性时,将不会调用函数的__get__方法。你知道吗

但是,函数的__get__方法负责将函数的第一个参数(通常称为self)绑定到所讨论的实例(从而创建一个方法)。你知道吗

如果要从任意实例上的任意函数创建方法,仍然可以手动调用__get__。这可能有点愚蠢,因为您甚至可以将第一个函数参数绑定到某个实例,然后将该方法设置为另一个对象的属性;)

>>> class Unrelated: 
...:     pass 
...:
>>> u = Unrelated()                                                                                                                   
>>> u.foo = (lambda self, x, y: print(self, x+y)).__get__(m1)                                                          
>>> u.foo(3, 4)                                                                                                        
<myClass object> 7

相关问题 更多 >