有没有办法在 python 中使用点运算符传递参数?

Posted

技术标签:

【中文标题】有没有办法在 python 中使用点运算符传递参数?【英文标题】:Is there a way to pass arguments using the dot operator in python? 【发布时间】:2015-06-05 12:49:34 【问题描述】:

我想创建一个干净、“智能”的方法,该方法无需传入参数即可执行特定操作。我有一些原则上工作的代码如下:

class Foo():
    def __init__(self, spam='spam', ham='ham'):
        self.spam = spam
        self.ham = ham

    def bar(self, arg):
        # spam operation
        if arg == self.spam:
            return self.spam*2
        # ham operation
        elif arg == self.ham:
            return self.ham*3

请注意,bar 方法用于对 spamham 执行不同的操作。实现此代码将返回:

foo = Foo()
foo.bar(foo.spam)                      # returns 'spamspam'
foo.bar(foo.ham)                       # returns 'hamhamham'

不幸的是,我必须使用两次foo 才能访问bar 中的特定操作,这既尴尬又乏味。有没有一种更简洁的 Pythonic 方法可以在不传递参数的情况下获得相同的结果?例如,是否可以重载点 (.) 运算符以获得相同的结果:

# Ideal 1
foo = Foo()
foo.bar.spam                          # bar knows to use spam operation
foo.bar.ham                           # bar knows to use ham operation    

甚至更好

# Ideal 2
foo = Foo()
foo.spam.bar                          # bar knows to use spam operation
foo.ham.bar                           # bar knows to use ham operation     

【问题讨论】:

您可以将bar 设为类而不是def,然后在bar 上重载__getattribute__ 这里有个问题 - 为什么你要为这两个都打电话给bar?为什么不直接创建foo.barspam()foo.barham()?这些中的每一个都可以在内部调用 bar 方法,并使用最终调用者不需要关心的正确参数。如果这些实际上是您引用的固定内部变量,那么动态调度它似乎很愚蠢。 谢谢@wim。您的建议在我编辑之前是合适的(理想 1)。我会试试这个。不确定如何/是否适用于 Ideal 2。 @Amber 这对于写的 Ideal1 案例来说是一个很好的观点,所以我进行了编辑以添加 Ideal 2(我真正想要的)。我希望用户能够灵活地使用foo.spam 访问属性或使用foo.spam.bar 快速返回操作。谢谢。 我觉得__getattr__可以满足你的需要。 【参考方案1】:

编辑:更新为参数化选项。

这是使用对象组合的东西:

class Pork(object):
    def __init__(self, name, mult):
        self.name = name
        self.mult = mult

    @property
    def bar(self):
        return self.name * self.mult

    def __repr__(self):
        return self.name

class Foo(object):
    def __init__(self, spam='spam', ham='ham'):
        self.spam = Pork(spam, 2)
        self.ham = Pork(ham, 3)

结果:

In [638]: foo = Foo()

In [639]: foo.spam.bar
Out[639]: 'spamspam'
In [641]: foo.ham.bar
Out[641]: 'hamhamham'

【讨论】:

很好的答案!这几乎解决了我的问题。为了完整起见,我建议添加适当的条件语句以返回正确的 foo.ham.bar 值。 @salparadise 我会等你编辑然后接受答案,或者我可以为你编辑。非常感谢。 @pylang 有很多方法可以给猫剥皮,但我认为参数化您想要打印的次数是一种好方法。如果您正在寻找其他东西,请告诉我。 感谢@salparadise,您优雅地回答了我的问题。仅供读者参考 - 这种方法在使用传递字符串时非常有效。 __repr__ 似乎返回一个 str 并将 obj 表示更改为字符串。但是,传递其他类型并不能很好地工作,即带有(将 __repr__ 替换为 __int____float__)的数字,不适用于列表。再次感谢。

以上是关于有没有办法在 python 中使用点运算符传递参数?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中通过三元运算符传递函数参数

有没有办法在接口 [Golang] 中传递多个参数? [关闭]

如果传递了另一个参数,则 Python 函数使参数成为强制性参数

将列表作为查询参数传递[重复]

Nagios - 如何在传递给 NRPE 服务器的参数中使用逻辑运算符

在 Robot Framework 中传递 *args