当前位置: 首页 > 面试题库 >

Python是否有匿名类?

越霖
2023-03-14
问题内容

我想知道Python是否具有类似C#匿名类功能的东西。为了澄清,这是一个示例C#代码段:

var foo = new { x = 1, y = 2 };
var bar = new { y = 2, x = 1 };
foo.Equals(bar); // "true"

在Python中,我会想象这样的事情:

foo = record(x = 1, y = 2)
bar = record(y = 2, x = 1)
foo == bar  # true

特定要求是能够在表达式上下文中创建具有指定字段的对象(例如,可在lambda和不允许使用语句的其他地方使用),而无需其他外部声明,并且能够通过普通成员按名称访问各个组件访问语法foo.bar。创建的对象还应按
组件名称 (而不是像元组那样按位置)实现结构比较。

特别是:元组不是因为它们的组件没有命名;类不是因为它们需要声明;dict是不是因为它们具有不希望使用的foo["bar"]语法来访问组件。

namedtuple是不是,因为即使您内联定义类型,它仍然需要一个名称,并且比较是基于位置的,而不是基于名称的。特别是:

 def foo(): return namedtuple("Foo", "x y")(x = 1, y = 2)
 def bar(): return namedtuple("Foo", "y x")(x = 1, y = 2)
 foo() == bar()   # False because fields are compared in order, and not by name
                  # True would be desired instead

我知道如何在需要时用Python编写这样的东西。但是我想知道Python标准库或任何流行的第三方库中是否有类似的东西。

[编辑]

仅出于此目的,这是一个单表达式解决方案,它结合了Ken和alanlcode的两个非常有用的答案,从而产生结构上的相等而没有任何额外的外部声明:

type("", (), { \
    "__init__": (lambda self, **kwargs: self.__dict__.update(kwargs)), \
    "__eq__": (lambda self, other: self.__dict__ == other.__dict__) } \
)(x = 1, y = 2)

从技术上讲,它可以满足问题的所有要求,但我衷心希望没有人会使用它(我绝对不会)。


问题答案:

pythonic的方式是使用dict

>>> foo = dict(x=1, y=2)
>>> bar = dict(y=2, x=1)
>>> foo == bar
True

满足您的所有要求,除了您仍然需要foo['x']代替foo.x

如果有问题,您可以轻松定义一个类,例如:

class Bunch(object):
    def __init__(self, **kwds):
        self.__dict__.update(kwds)

    def __eq__(self, other):
        return self.__dict__ == other.__dict__

或者,一个不错的矮个子

class Bunch(dict):
    __getattr__, __setattr__ = dict.get, dict.__setitem__

(但是请注意,第二点有问题,正如Alex在评论中指出的那样!)



 类似资料:
  • 问题内容: 在Java中,您可以使用匿名内部类内联定义一个新类。当您只需要重写类的单个方法时,这很有用。 假设您要创建一个仅覆盖单个方法的子类(例如)。在Java中,您可以编写如下代码: 这段代码创建了一个匿名类,该类仅扩展和覆盖方法。 Python中有类似的习语吗?在这些情况下使用哪种习语? 问题答案: 您可以使用内建函数即时创建类。例如: 由于OptionParser不是新式类,因此您必须显式

  • 问题内容: 例如,我可能想进行如下分配(在JavaScript中): 在Java中,如何使用Lambdas做类似的事情?编译器不喜欢这样的东西: 问题答案: 否,因为Lambda需要目标类型。您所能做的最好是将表达式转换为: 您必须为特定的lambda使用正确的功能接口。如您所见,它非常笨拙,没有用。 更新 上面的代码是JavaScript代码的直接翻译。但是,直接转换代码并不能总是获得最佳结果。

  • 例如,我可能想做这样的作业(在JavaScript中): 在Java中,我如何使用Lambdas做类似的事情?编译器不喜欢这样的东西:

  • 本文向大家介绍Python中的匿名函数,包括了Python中的匿名函数的使用技巧和注意事项,需要的朋友参考一下 这些函数被称为匿名函数,因为它们不是通过使用def关键字以标准方式声明的。您可以使用lambda关键字创建小的匿名函数。 Lambda形式可以接受任意数量的参数,但仅以表达式形式返回一个值。它们不能包含命令或多个表达式。 匿名函数不能直接调用print,因为lambda需要一个表达式 L

  • 问题内容: 考虑以下代码: Java将如何对待类? 对于200个对象中的每个对象,是否都将其视为不同的类? 即使在创建第一个对象之后,性能也会受到影响吗? 是否以某种方式对其进行缓存? 我只是好奇 :) 问题答案: 每次通过循环都创建一个匿名类的新 实例 ,这并不是每次都重新定义或重新加载该类。该类定义一次(在编译时),并且一次加载(在运行时)。 使用匿名类不会对性能产生重大影响。

  • 我试图用java创建一个anon类 它似乎根本不起作用,它给了我一个错误,说run()方法未定义。尽管我创建了一个包含run()方法的anon类,但我是一个完全的java初学者,我大部分时间用javascript编写代码,javascript是我最熟悉的语言,我正在努力适应java的概念,所以对这里的很多人来说,这个问题可能看起来很愚蠢,我为此道歉。提前谢谢