Lambda不是';t在Python 3.6中创建实例方法

Lambda不是';t在Python 3.6中创建实例方法,python,lambda,Python,Lambda,我试图创建名称基于类实例特定属性的方法。我的代码与此类似: 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:

我试图创建名称基于类实例特定属性的方法。我的代码与此类似:

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

(有点)回复wim的评论:

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


您只是在设置一个属性,该属性恰好是实例上的一个函数

函数是(非数据)函数,您可以使用它们的
\uuuu get\uuu
方法修复第一个参数

演示:


你为什么这么做?这解决了在类创建时简单地定义方法所不能解决的问题吗?类提供的方法对于所有实例都应该是相同的。在调用
create\u方法之前,实例是否可以提供自己版本的
info\u供访问?听起来你只是想要一本字典,而不是一套方法。(或者使用一种方法
get
为您查找字典。)为了回答您的问题,我编辑了原始帖子。从描述中确实不清楚您想要什么。然而,听起来像是myClass存在的唯一原因是用方法调用代替字典查找。这似乎是对时间和精力的巨大浪费。为什么要经历像
d={'foo':'bar'}这样的麻烦;myClass(d).foo()
当你可以直接使用
d['foo']
时?因为我在现实生活中没有使用字典,所以这只是一个更简单的例子,让它更容易理解。-1这是一个非常愚蠢的想法,我甚至不认为这是OP提出的问题。方法应该存在于类对象上,而不是实例上。我将此标记为答案,因为timgeb明白了我问题的重点:它更多的是好奇,而不是实际应用或最佳解决方案。我喜欢元编程,并且对这个问题非常好奇,这个答案非常有趣,它深入解释了描述符是如何工作的(我以前不知道)。非常感谢您的帮助,先生。
14
>>> 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
>>> class Unrelated: 
...:     pass 
...:
>>> u = Unrelated()                                                                                                                   
>>> u.foo = (lambda self, x, y: print(self, x+y)).__get__(m1)                                                          
>>> u.foo(3, 4)                                                                                                        
<myClass object> 7