Python:链接命令

Python:链接命令,python,set,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(

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

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)
我想知道是否有任何方法也可以链接像这样的命令,也许是一些括号技巧?

集合有适当的方法,以及返回新对象的方法
str
对象是不可变的,因此没有就地方法,因此只剩下返回新对象的方法

set.update()
在适当的位置更改集合,因此您不能使用它来链接,不。但是如果您使用它,您会得到完全相同的结果,但作为一个新集合:

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

print len(set1 | set2)
您可以根据需要将这些链接起来:

print len(set1 | set2 | set3)
您可能会注意到,像
set.union()
这样的方法被列为可用于
set()
frozenset()
类型,后者是不可变的类型。但是,像
set.update()
这样的方法单独列出,因为它们仅可用于可变的
set()
类型。

集合具有就地方法以及返回新对象的方法
str
对象是不可变的,因此没有就地方法,因此只剩下返回新对象的方法

set.update()
在适当的位置更改集合,因此您不能使用它来链接,不。但是如果您使用它,您会得到完全相同的结果,但作为一个新集合:

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

print len(set1 | set2)
您可以根据需要将这些链接起来:

print len(set1 | set2 | set3)

您可能会注意到,像
set.union()
这样的方法被列为可用于
set()
frozenset()
类型,后者是不可变的类型。但是,像
set.update()
这样的方法单独列出,因为它们仅适用于可变的
set()
类型。

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

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)

正如其他人所提到的,您可以经常使用诸如
+
|
之类的运算符来获取所需内容。如果您更喜欢运算符链接,但需要就地执行操作,则可以编写一个包装器类来执行此操作

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)


简洁的代码更漂亮不,一点也不。代码越清晰、越不密集越好。请查看“模糊代码”,它们非常简洁,但完全不可读。那么,为什么要用
set1
set2
的联合来更新
set3
,而它已经通过
set.update()
调用包含了联合?我同意,有些人在一行中塞得太多了。但看看我选择的例子。在这样的情况下,您愿意选择后者吗?@DarshanChaudhary不,我更愿意在多行上进行显式调用。@DarshanChaudhary:应该使用什么取决于您的用例。例如,当您可以更新现有的
set()
对象并避免额外的内存开销时,通过链接避免创建全新的
set()
对象可能并不理想。简洁的代码更漂亮不,一点也不。代码越清晰、越不密集越好。请查看“模糊代码”,它们非常简洁,但完全不可读。那么,为什么要用
set1
set2
的联合来更新
set3
,而它已经通过
set.update()
调用包含了联合?我同意,有些人在一行中塞得太多了。但看看我选择的例子。在这样的情况下,您愿意选择后者吗?@DarshanChaudhary不,我更愿意在多行上进行显式调用。@DarshanChaudhary:应该使用什么取决于您的用例。例如,当您可以更新现有的
set()
对象并避免额外的内存开销时,通过链接避免创建全新的
set()
对象可能并不理想。您的意思是“
set
对象是不可变的…”?@DarshanChaudhary:不,
frozenset()
对象是不可变的,
set()
对象是可变的。确定。因此,没有办法链接更改对象的命令(例如
set.update()
list.sort()
等)?@DarshanChaudhary:不,对象上没有方法变异对象并在变异后返回对象本身。您必须为此编写单独的函数。您的意思是“
set
对象是不可变的…”吗@DarshanChaudhary:不,
frozenset()
对象是不可变的,
set()
对象是可变的。确定。因此,没有办法链接更改对象的命令(例如
set.update()
list.sort()
等)?@DarshanChaudhary:不,对象上没有方法变异对象并在变异后返回对象本身。您必须为此编写单独的函数。这太棒了!介意把代码分解一下或者指出一些有用的链接吗+1@DarshanChaudhary-添加评论,希望有帮助。这太棒了!介意把代码分解一下或者指出一些有用的链接吗+1@DarshanChaudhary-添加评论,希望有帮助。