开发者

chain the function as shell pipe command in python

In Unix/linux shell we can:

seq 0 100 | head -10 | awk 'NF%2==0' | awk 'NF%2==1' | rev

Now I defined:

seqsrc = list(range(0,100))

def all(src): return src
def head(src, count, offset = 0): return src[:count]
def tail(src, count, offset = 0): return src[-count:]
def odd(src): return [x for x in src if x % 2 != 0]
def even(src): return [x for x in src if x % 2 == 0]
def reverse(src): return src[::1]
...
#def other_sequence_manpulation_method()

Here are my questions:

1. How can I get shell pipe like grammar in python?

seqdst = all(seqsrc).head(10).odd().even().reverse()

2. For some reason I want to enumerate all possible combinations of those simple functi开发者_开发问答ons I defined, can I do it with itertools.product() to generate combinations - EDIT: as well as for the Seq class solution below?

possible_head_limit = [10,20,30]

all(seqsrc).head(10)                    # 10 is one item in possible_head_limit
all(seqsrc).head(10).odd()
all(seqsrc).head(10).odd().even()
all(seqsrc).head(10).odd().even().reverse()
all(seqsrc).head(10).even()
all(seqsrc).head(10).even().odd()
....
all(seqsrc).head(20)                    # 20 is one item in possible_head_limit

all(seqsrc).head(20).odd()
...

3: Suppose seqsrc = range(0,10) then head(20) may return same as head(10) or sometime it is meanless

all(seqsrc).head(20).odd().even().reverse()  
# = all(seqsrc).head(10).odd().even().reverse() 
# = all(seqsrc).head(11).odd().even().reverse()
# ...

Can I add control function in the method chain, then I can control the mean of the return?

ignore_insufficient(True).all(seqsrc).head(20).odd().even().reverse()
ignore_insufficient(False).all(seqsrc).head(20).odd().even().reverse()  # it will print some sort of error

# or even I can control each function I defined?
ignore_insufficient(True).all(seqsrc).\
ignore_insufficient(True).head(20).\
ignore_insufficient(False).tail(10)

Thanks!


There are many questions in your post and I'm not certain to understand them all. However, here is a starting point.

Chainable methods are usually implemented by designing classes with methods that return new instances of the class itself. This allows to call further methods from the return value of previous methods.

Therefore, you can define a Seq class as follows:

class Seq(object):
    def __init__(self, seq):
        self.seq = seq
    def __repr__(self):
        return repr(self.seq)
    def __str__(self):
        return str(self.seq)
    def all(self):
        return Seq(self.seq[:])
    def head(self, count):
        return Seq(self.seq[:count])
    def tail(self, count):
        return Seq(self.seq[-count:])
    def odd(self):
        return Seq(self.seq[1::2])
    def even(self):
        return Seq(self.seq[::2])
    def reverse(self):
        return Seq(self.seq[::-1])

And use it like:

>>> s = Seq(range(0, 100))
>>> print s.head(10).odd().even().reverse()
[9, 5, 1]

Note that this can be improved in many ways. For instance, in the Javascript world, jQuery's chainable methods actually push their results into a stack, thus allowing backtracking in the history of calls and restoring a previous context. See end() for details.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜