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-添加评论,希望有帮助。