随便来一个好玩的自加对象
>>> add = type('_', (int,), {'__call__': lambda s,x:add(s.numerator+x)}) >>> add(1) 1 >>> add(1)(2) 3 >>> add(1)(2)(3)(4)(5) 15 >>>
再来一个管道操作
>>> from functools import partial >>> F = type('_', (partial,), {'__ror__': lambda s,o: s(*o) if isinstance(o, tuple) else s(o)}) >>> [2,3]|F(sum) 5 >>> range(10) | F(filter, lambda x: x % 2) | F(sum) 25 >>>
python 的花招,只要不考虑运行效率,主要就是 A. 玩那一堆 __xxxx__ 函数, B. 下面几个自带的库 import ast import inspect import functools import ctypes C. 和这个函数 id() A,B,C 基本可以让你为所欲为
#谨慎使用 import inspect import functools import ctypes class PyObject(ctypes.Structure): class PyType(ctypes.Structure): pass ssize = ctypes.c_int64 if ctypes.sizeof(ctypes.c_void_p) == 8 else ctypes.c_int32 _fields_ = [ ('ob_refcnt', ssize), ('ob_type', ctypes.POINTER(PyType)), ] def incref(self): self.ob_refcnt += 1 def decref(self): self.ob_refcnt -= 1 def sign(klass,value): class SlotsProxy(PyObject): _fields_ = [('dict', ctypes.POINTER(PyObject))] name = klass.__name__ target = klass.__dict__ proxy_dict = SlotsProxy.from_address(id(target)) namespace = {} ctypes.pythonapi.PyDict_SetItem( ctypes.py_object(namespace), ctypes.py_object(name), proxy_dict.dict, ) namespace[name]["签名"] = value # 修改 built-in str sign(str,"某某人专用") >>> "1234567".签名 '某某人专用' >>> >>> "abcde".签名.签名.签名.签名.签名.签名.签名 '某某人专用' >>>
#土制 单参化
import inspect import functools def uargs(f): arg_names = inspect.getfullargspec(f).args def _func(arg_names,d): args = [] for i in range(len(arg_names)): #necessary for version < 3.5 to keep order k = arg_names[i] args.append(d[k]) return(f(*args)) func = functools.partial(_func,arg_names) return(func) def cufunc(a,b,c,d): print(a,b,c,d) myfunc = uargs(cufunc) myfunc = uargs(cufunc) myfunc({"a":100,"b":200,"c":300,"d":400}) 100 200 300 400
# 土制 库里化
import inspect import functools class curry(): def goose(): def egg(*args): egg.arguments.extend(args) return(egg) egg.__setattr__("arguments",[]) return(egg) def __init__(self,orig_func): params_count = inspect.getfullargspec(orig_func).args.__len__() self.orig_func = orig_func self.params_count = params_count self.egg = goose() def __call__(self,*args): count = self.params_count orig_func = self.orig_func egg = self.egg egg(*args) args_lngth = len(egg.arguments) if(args_lngth<count): return(self) else: args = egg.arguments egg.arguments = [] return(orig_func(*args)) def __repr__(self): return(self.egg.arguments.__repr__()) def cufunc(a,b,c,d): print(a,b,c,d) myfunc = curry(cufunc) myfunc(10) myfunc(20) myfunc(30)(40) #10 20 30 40
python 因为暴露了 id()函数 和ctypes,可以认为python里没有primitive 和native/built-in,也就意味着基本上你想做什么都可以
>>> a=1 >>> b=2 >>> a,b=b,a >>> a 2 >>> b 1
a = b = c = 50
>>> a,b,c = [1,2,3] >>> a 1 >>> b 2 >>> c 3 >>> >>> >>> a, *others = [1,2,3,4] >>> a 1 >>> others [2, 3, 4] >>>
a = 15 if (10 < a < 20): print("Hi")
等价于
a = 15 if (a>10 and a<20): print("Hi")
>>> [5,2]*4 [5, 2, 5, 2, 5, 2, 5, 2]
>>> "hello"*3 'hellohellohello'
age = 30 slogon = "牛逼" if age == 30 else "niubility"
等价于
if age == 30: slogon = "牛逼" else: slogon = "niubility"
>>> a= {"a":1} >>> b= {"b":2} >>> {**a, **b} {'a': 1, 'b': 2} >>>
>>> s = "i love python" >>> s[::-1] 'nohtyp evol i' >>>
>>> s = ["i", "love", "pyton"] >>> " ".join(s) 'i love pyton' >>>
检查列表foo是否有0,有就提前结束查找,没有就是打印“未发现"
found = False for i in foo: if i == 0: found = True break if not found: print("未发现")
如果用 for else 语法来写可以省几行代码
for i in foo: if i == 0: break else: print("未发现")
>>> m = {x: x**2 for x in range(5)} >>> m {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} >>>
>>> content = ["a", "b", "c", "a", "d", "c", "a"] >>> from collections import Counter >>> c = Counter(content) >>> c.most_common(1) [('a', 3)] >>>
出现第1多的元素是a,一共出现3次, 你也可以用类似的方法找出第二多或者第三多的
给字典中的value设置为列表,普通方法
>>> d = dict() if 'a' not in d: d['a'] = [] d['a'].append(1)
使用defaultdict
默认字典构建一个初始值为空列表的字典
from collections import defaultdict d = defaultdict(list) d['a'].append(1)
这是3.8的新特性,赋值表达式又成为海象运算符:=, 可以将变量赋值和表达式放在一行,什么意思? 看代码就明白
>>> import re >>> data = "hello123world" >>> match = re.search("(d+)", data) # 3 >>> if match: # 4 ... num = match.group(1) ... else: ... num = None >>> num '123'
第3、4行 可以合并成一行代码
>>> if match:=re.search("(d+)", data): ... num = match.group(1) ... else: ... num = None ... >>> num '123'
isinstance
函数可用于判断实例的类型,其实第二个参数可以是多个数据类型组成的元组。例如:
isinstance(x, (int, float)) # 等价于 isinstance(x, int) or isinstance(x, float)
类似的函数还有字符串的startswith,endswith,例如:
s.startswith(('"""', "'''")) # 等价于 s.startswith("'''") or s.startswith('"""')
# python3 python3 -m http.server # python2 python -m SimpleHTTPServer 8000
效果如下,可以在浏览器共享文件目录,方便在局域网共享文件
>>> lang = {"python":".py", "java":".java"} >>> dict(zip(lang.values(), lang.keys())) {'.java': 'java', '.py': 'python'}
test = [1, 2, 3, 4, 2, 2, 3, 1, 4, 4, 4, 5] >>> max(set(test), key=test.count) 4
class MyClass(object): def __init__(self, name, identifier): self.name = name self.identifier = identifier self.set_up() print(sys.getsizeof(MyClass)) class MyClass(object): __slots__ = ['name', 'identifier'] def __init__(self, name, identifier): self.name = name self.identifier = identifier self.set_up() print(sys.getsizeof(MyClass)) # In Python 3.5 # 1-> 1016 # 2-> 888
>>> i = ['a','b','c'] >>> i.extend(['e','f','g']) >>> i ['a', 'b', 'c', 'e', 'f', 'g'] >>>
>>> a = [ 1, 2, 3] >>> a[-1] 3
>>> a = [0,1,2,3,4,5,6,7,8,9] >>> a[3:6] # 第3个到第6个之间的元素 [3, 4, 5] >>> a[:5] # 前5个元素 [0, 1, 2, 3, 4] >>> a[5:] # 后5个元素 [5, 6, 7, 8, 9] >>> a[::] # 所有元素(拷贝列表) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> a[::2] # 偶数项 [0, 2, 4, 6, 8] >>> a[1::2] # 奇数项 [1, 3, 5, 7, 9] >>> a[::-1] # 反转列表 [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
import itertools >>> a = [[1, 2], [3, 4], [5, 6]] >>> i = itertools.chain(*a) >>> list(i) [1, 2, 3, 4, 5, 6]
>>> a = ['Merry', 'Christmas ', 'Day'] >>> for i, x in enumerate(a): ... print '{}: {}'.format(i, x) ... 0: Merry 1: Christmas 2: Day
>>> le = [x*2 for x in range(10)] >>> le # 每个数乘以2 [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] >>> le = [x for x in range(10) if x%2 == 0] >>> le # 获取偶数项 [0, 2, 4, 6, 8]
>>> ge = (x*2 for x in range(10)) >>> ge <generator object <genexpr> at 0x01948A50> >>> next(ge) 0 >>> next(ge) 2 >>> next(ge) 4 ... >>> next(ge) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
Python >>> nums = {n**2 for n in range(10)} >>> nums {0, 1, 64, 4, 36, 9, 16, 49, 81, 25}
>>> d = {"1":"a"} >>> d['2'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: '2' >>> '1' in d True >>> d['1'] 'a' >>> d.get("1") 'a' >>> d.get("2") >>>
from functools import wraps def tags(tag_name): def tags_decorator(func): @wraps(func) def func_wrapper(name): return "<{0}>{1}</{0}>".format(tag_name, func(name)) return func_wrapper return tags_decorator @tags("p") def get_text(name): """returns some text""" return "Hello " + name print(get_text("Python")) >>><p>Hello Python</p>
>>> def sub_dicts(d, keys): ... return {k:v for k, v in d.items() if k in keys} ... >>> sub_dicts({1:"a", 2:"b", 3:"c"}, [1,2]) {1: 'a', 2: 'b'}
>>> d = {'a': 1, 'b': 2, 'c': 3, 'd': 4} >>> >>> zip(d.values(), d.keys()) <zip object at 0x019136E8> >>> z = zip(d.values(), d.keys()) >>> dict(z) {1: 'a', 2: 'b', 3: 'c', 4: 'd'}
>>> from collections import namedtuple >>> Point = namedtuple("Point", "x,y") >>> p = Point(x=1, y=2) >>> p.x 1 >>> p[0] 1 >>> p.y 2 >>> p[1] 2
>>> d = dict() >>> if 'a' not in d: ... d['a'] = [] ... >>> d['a'].append(1) >>> d {'a': [1]} >>> d.setdefault('b',[]).append(2) >>> d {'a': [1], 'b': [2]} >>>
>>> d = dict((str(x), x) for x in range(10)) >>> d.keys() # key 无序 dict_keys(['0', '1', '5', '9', '4', '6', '7', '8', '2', '3']) >>> from collections import OrderedDict >>> m = OrderedDict((str(x), x) for x in range(10)) >>> m.keys() # key 按照插入的顺序排列 odict_keys(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])
>>> import heapq a = [51, 95, 14, 65, 86, 35, 85, 32, 8, 98] >>> heapq.nlargest(5,a) [98, 95, 86, 85, 65] >>> heapq.nsmallest(5,a) [8, 14, 32, 35, 51] >>>
>>> with open('foo.txt', 'w') as f: ... f.write("hello") ...
list_1 = ["One","Two","Three"] list_2 = [1,2,3] dictionary = dict(zip(list_1, list_2)) print(dictionary)
my_list = [1,4,1,8,2,8,4,5] my_list = list(set(my_list)) print(my_list)
import calendar >>> print(calendar.month(2021, 1)) January 2021 Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
def add(a, b): return a+b
等价于
>>> add = lambda a,b:a+b >>> add(1,2) 3
如果对您有帮助,麻烦您给我点个小小的赞,后面我还会写更多实用技巧,关注我不迷路。如果还整准备入门,可以了解下面这个闯关式教学