python语法糖 常见问题_syntax_sugar:向Python添加很酷的语法糖

syntax_sugar 68747470733a2f2f7472617669732d63692e6f72672f637a68656f2f73796e7461785f73756761725f707974686f6e2e7376673f6272616e63683d6d617374657268747470733a2f2f696d672e736869656c64732e696f2f707970692f762f73796e7461785f73756761722e737667

This lib adds some anti-Pythonic "syntactic sugar" to Python.

NOTE: This is merely an experimental prototype to show some potential of operator overloading in Python. Only tested under Python 3.6.0. Anything may evolve without announcement in advance.

Also, you can watch the last part of this Matz's talk to understand the intuition behind this project.

68747470733a2f2f696d672e796f75747562652e636f6d2f76692f3438694b6a5563454e52452f302e6a7067

Install

pip install syntax_sugar

Use

To test out this lib, you can simply do.

from syntax_sugar import *

For serious use, you can explicitly import each component as explained below ... if you dare to use this lib.

pipe

from syntax_sugar import pipe, END

from functools import partial

pipe(10) | range | partial(map, lambda x: x**2) | list | print | END

# put 10 into the pipe and just let data flow.

# output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# remember to call END at the end

# NOTE: everything in the middle of the pipe is just normal Python functions

pipe(10) | range | (map, lambda x: x**2) | list | print | END

# Tuples are shortcuts for partial functions

from syntax_sugar import each

x = pipe(10) | range | each(lambda x: x ** 2) | END

# `each` is just a shortcut of the partial function of `map`

# We can also save the result in a variable

pipe(10) | range | each(str) | ''.join > 'test.txt'

# wanna write to a file? Why not!

# write "0123456789" to test.txt

# We don't need to put END here.

We can connect multiple pipes to create a longer pipe

from syntax_sugar import pipe, each, END

from functools import reduce

p1 = pipe(10) | range | each(lambda x: x/2)

# head pipe can have input value

p2 = pipe() | (reduce, lambda acc, x: (acc + x)/2)

p3 = pipe() | int | range | sum

# middle pipes can have no input value

p1 | p2 | p3 | END

# returns 6

# you can also put a different value in the pipe

p = p1 | p2 | p3

p(20)

# returns 36

pipe with parallelism

By default, pipe works with threads.

You can have a function running in a seperate thread with pipe. Just put it in a [] or more explicitly t[]. Threads and processes are also available.

from syntax_sugar import (thread_syntax as t,

process_syntax as p)

pipe(10) | [print] | END # print run in a thread

pipe(10) | t[print] | END # print run in a thread

pipe(10) | p[print] | END # print run in a process

What makes this syntax good is that you can specify how many threads you want to spawn, by doing [function] * n where n is the number of threads.

pipe([1,2,3,4,5]) | [print] * 3 | END # print will run in a ThreadPool of size 3

Here is an example of requesting a list of urls in parallel

import requests

(pipe(['google', 'twitter', 'yahoo', 'facebook', 'github'])

| each(lambda name: 'http://' + name + '.com')

| [requests.get] * 3 # !! `requests.get` runs in a ThreadPool of size 3

| each(lambda resp: (resp.url, resp.headers.get('Server')))

| list

| END)

# returns

# [('http://www.google.com/', 'gws'),

# ('https://twitter.com/', 'tsa_a'),

# ('https://www.yahoo.com/', 'ATS'),

# ('https://www.facebook.com/', None),

# ('https://github.com/', 'GitHub.com')]

infix function

from syntax_sugar import is_a, has, to, step, drop

1 /is_a/ int

# equivalent to `isinstance(1, int)`

range(10) /has/ '__iter__'

# equivalent to `hasattr(range(10), "__iter__")`

1 /to/ 10

# An iterator similar to `range(1, 11)`.

# Python's nasty range() is right-exclusive. This is right-inclusive.

10 /to/ 1

# We can go backward.

'0' /to/ '9'

# We can also have a range of characters :)

1 /to/ 10 /step/ 2

# We can also specify step sizes.

# Similar to `range(1, 11, 2)`

10 /to/ 1 /step/ 2

# Go backward.

# Similar to `range(10, 0, -2)`

1 /to/ 10 /drop/ 5

# there is a `drop` functon which drop N items from the head

# An iterator similar to [6, 7, 8, 9, 10]

/to/ has some advanced features

lazy evaluation.

support infinity.

support product operation.

support pipe.

from syntax_sugar import INF, take, each

# CAUTION: this will infinitely print numbers

for i in 1 /to/ INF:

print(i)

list(1 /to/ INF /take/ 5)

# there is a `take` functon which is similar to itertools.islice

# return [1, 2, 3, 4, 5]

list(0 /to/ -INF /step/ 2 /take/ 5)

# also works with negative infinity.

# return [0, -2, -4, -6, -8]

list((1 /to/ 3) * (4 /to/ 6))

# all combinations of [1..3] * [4..6]

# return [(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]

1 /to/ 10 /take/ 5 | each(lambda x: x **2) | list | END

# These infix functions can also be piped.

# [1, 4, 9, 16, 25]

Make your own infix function, so you can append multiple items to a list in one line.

from syntax_sugar import infix

@infix

def push(lst, x):

lst.append(x)

return lst

[] /push/ 1 /push/ 2 /push/ 3

# returns [1,2,3]

function composition

In math, (f * g) (x) = f(g(x)). This is called function composition.

# lmap equivalent to `list(map(...))`

lmap = compose(list, map)

lmap(lambda x: x ** 2, range(10))

Let's say we want to represent f * g * h in a program, i.e. fn(x) = f(g(h(x)))

f = lambda x: x**2 + 1

g = lambda x: 2*x - 1

h = lambda x: -2 * x**3 + 3

fn = compose(f, g, h)

fn(5) # 245026

or you can do

f = composable(lambda x: x**2 + 1)

g = composable(lambda x: 2*x - 1)

h = composable(lambda x: -2 * x**3 + 3)

fn = f * g * h

fn(5) # 245026

Sometimes you may prefer the decorator way.

# make your own composable functions

@composable

def add2(x):

return x + 2

@composable

def mul3(x):

return x * 3

@composable

def pow2(x):

return x ** 2

fn = add2 * mul3 * pow2

# equivalent to `add2(mul3(pow2(n)))`

fn(5)

# returns 5^2 * 3 + 2 = 77

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值