Python:链接命令

时间:2015-10-02 18:29:39

标签: python set

简洁的代码更漂亮。所以,我会去

str_ = "Hello World    "
print str_.strip().replace(" ", "-").lower()

与:相比:

str_ = "Hello World    "
str_ = str_.strip()
str_ = str_.replace(" ", "-")
str_ = str_.lower()
print str_

但是,如果函数返回不兼容的对象(例如None),则无法正常工作。

案例:

set1 = set([1, 2, 3])
set2 = set([1, 3, 5])
set3 = set()
set3.update(set1) #returns None
set3.update(set2)
set3.update(set1.union(set2))
print len(set3)

我想知道是否有任何方法可以链接这些命令,也许是一些括号技巧?

2 个答案:

答案 0 :(得分:5)

设置就地方法,以及返回 new 对象的方法。 str个对象是不可变的,因此没有就地方法,因此只剩下返回新对象的方法。

set.update()就地改变了这一套,所以你不能用它来链,不。但是,如果您使用set.union()代替完全相同的结果,而是作为集:

set1 = set([1, 2, 3])
set2 = set([1, 3, 5])
print len(set1.union(set2))

set.union()也可以使用|运算符表示:

print len(set1 | set2)

您可以根据需要进行链接:

print len(set1 | set2 | set3)

您可能会注意到,set.union()等方法列为set()frozenset()类型,后者是不可变类型。但是,set.update()等方法会单独列出,仅适用于可变set()类型。

答案 1 :(得分:1)

正如其他人所提到的,您可以经常通过+|等运营商获得所需内容。如果您更喜欢操作符链接但需要就地执行操作,则可以编写一个包装类来执行操作。

class Chainer(object):

    """A proxy object that allows an object's methods be chained even
    if the methods themselves to not return a reference to the object.
    When object methods return a reference to self, several calls can
    be made on the object as in `someobj.method1().method2()` and etc...
    """

    def __init__(self, target):
        """Create a chaining proxy to target"""
        self.target = target

    def __getattr__(self, attr):
        if attr == 'target':
            # let access to the proxied object through
            return self.__dict__['target']
        else:
            # get the proxied object attribute
            fctn = getattr(self.__dict__['target'], attr)
            if callable(fctn):
                # return a function that will call the proxied method, ignore
                # the return value and return a reference to the
                # proxy. The returned proxy can be used to call object
                # methods again.
                def caller(*args, **kw):
                    fctn(*args, **kw)
                    return self
                return caller
            else:
                return fctn


set1 = set([1, 2, 3])
set2 = set([1, 3, 5])
set3 = Chainer(set())
print len(set3.update(set1).update(set2).update(set1.union(set2)).target)