Python 有匿名类吗? [英] Does Python have anonymous classes?

查看:51
本文介绍了Python 有匿名类吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道 Python 是否有类似 C# 匿名类的功能.为了澄清,这里有一个示例 C# 片段:

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

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

foo = record(x = 1, y = 2)条 = 记录(y = 2,x = 1)foo == bar # 真

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

特别是:元组不是因为它们的组件没有命名;类不是因为它们需要声明;dicts 不是因为它们具有不需要的 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 因为字段是按顺序比较的,而不是按名称比较# True 会被取代

如果需要,我知道如何用 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 == 酒吧真的

满足您的所有要求,除了您仍然必须执行 foo['x'] 而不是 foo.x.

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

class Bunch(object):def __init__(self, **kwds):self.__dict__.update(kwds)def __eq__(自我,其他):返回 self.__dict__ == other.__dict__

或者,一个漂亮而简短的

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

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

I'm wondering if Python has anything like the C# anonymous classes feature. To clarify, here's a sample C# snippet:

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

In Python, I would imagine something like this:

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

The specific requirement is being able to create an object with specified fields in expression context (e.g. usable in lambdas and other places where statements aren't allowed), with no additional external declarations, and ability to access individual components by name via the normal member access syntax foo.bar. The created object should also implement structural comparison by component names (not by position, as tuples do).

In particular: tuples isn't it because their components are not named; classes isn't it because they require a declaration; dicts isn't it because they have undesired foo["bar"] syntax to access components.

namedtuple isn't it, because it still requires a name even if you define the type inline, and the comparison is position-based, not name-based. In particular:

 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

I know how to write such a thing in Python if needed. But I would like to know if there's anything like that in the Python standard library, or any popular third-party libraries.

[EDIT]

Just for the sake of it, here's a single-expression solution that combines two very informative answers by Ken and alanlcode, yielding structural equality without any extra outside declarations:

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

Technically, it satisfies all the requirements of the question, but I sincerely hope that no-one ever uses it (I definitely won't).

解决方案

The pythonic way would be to use a dict:

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

Meets all your requirements except that you still have to do foo['x'] instead of foo.x.

If that's a problem, you could easily define a class such as:

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

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

Or, a nice and short one

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

(but note that this second one has problems as Alex points out in his comment!)

这篇关于Python 有匿名类吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆