Antkillerfarm Hacking V7.0

Python(二)

2018-02-19

Python

类型建议符

def twoSum(num1: int, num2: int=100) -> int:

值得注意的是,类型建议符并非强制规定和检查,也就是说即使传入的实际参数与建议参数不符,也不会报错。

类似的,typing.cast并不是用来转换数据类型的,它是用来在类型提示中进行类型断言的。


此外,还有pyi文件用于辅助类型检测。

https://blog.csdn.net/weixin_40908748/article/details/106252884

什么是.pyi文件?

pass语句

def iplaypython():
       pass

定义一个函数iplaypython,但函数体部分暂时还没有完成,又不能空着不写内容,因此可以用pass来替代占个位置。

对象的属性

__dict__:对象的可变属性。

__slots__:对象的不可变属性,一旦创建就不可修改。

不是所有的对象都有__dict__属性,但多数对象有。

dir(Foo()):列出Foo()创建的对象的所有属性(不仅包括__dict____slots__,还包括其他的属性)。

参考:

http://www.cnblogs.com/ifantastic/p/3768415.html

dir()与__dict____slots__的区别

Typer

一个命令行选项的快速处理的库。

官网:

https://typer.tiangolo.com/

它的设计参考了FastAPI,后者是一个Web版本的API接口库,用于提供restful风格的API。

官网:

https://fastapi.tiangolo.com/

yield

yield就是return返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后(下一行)开始。

参考:

https://www.jianshu.com/p/d09778f4e055

彻底理解Python中的yield

with

Python的with语句允许我们非常方便地使用资源,而不必担心资源没有关闭。例如:

with open('/path/to/file', 'r') as f:
    f.read()

任何对象,只要正确实现了上下文管理,就可以用于with语句。

实现上下文管理是通过__enter__和__exit__这两个方法实现的:

class Query(object):

    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print('Begin')
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type:
            print('Error')
        else:
            print('End')

    def query(self):
        print('Query info about %s...' % self.name)

编写__enter__和__exit__仍然很繁琐,因此Python的标准库contextlib提供了更简单的写法:

from contextlib import contextmanager

@contextmanager
def tag(name):
    # __enter__
    print("<%s>" % name)
    yield
    # __exit__
    print("</%s>" % name)

with tag("h1"):
    print("hello")
    print("world")

上述代码执行结果为:

<h1>
hello
world
</h1>

with语句首先执行yield之前的语句,因此打印出<h1>;yield调用会执行with语句内部的所有语句,因此打印出hello和world;最后执行yield之后的语句,打印出</h1>

参考:

https://www.liaoxuefeng.com/wiki/1016959663602400/1115615597164000

contextlib

Singleton

class NewInt(object):
    _singleton = None
    def __new__(cls, *args, **kwargs):
        if not cls._singleton:
            cls._singleton = object.__new__(cls, *args, **kwargs)
        return cls._singleton

__init__.py的作用

__init__.py文件的作用是将文件夹变为一个Python模块,Python中的每个模块的包中,都有__init__.py文件。

示例:

# package
# __init__.py
import re
import urllib
import sys
import os

# a.py
import package 
print(package.re, package.urllib, package.sys, package.os)

__init__.py中还有一个重要的变量,__all__,它用来将模块全部导入。

# __init__.py
__all__ = ['os', 'sys', 're', 'urllib']

# a.py
from package import *

参见:

http://www.cnblogs.com/Lands-ljk/p/5880483.html

Python __init__.py作用详解

import

import subpackage1.a # 将模块subpackage.a导入全局命名空间,例如访问a中属性时用subpackage1.a.attr
from subpackage1 import a # 将模块a导入全局命名空间,例如访问a中属性时用a.attr_a
from subpackage.a import attr_a # 将模块a的属性直接导入到命名空间中,例如访问a中属性时直接用attr_a

上面的例子给出了import子目录文件的方法。如果是父目录呢?

import sys
sys.path.append("..")
import subpackage1.a # 假设subpackage1在../下

使用上法还可以导入任意目录,只需要将路径加入sys.path即可。可以是相对路径,也可以是绝对路径。

Slice

L[3:10:2]

第一个数表示切片开始的位置,第二个数表示切片到哪里结束,第三个数表示切片间隔数。

可以用负数做切片。负数用在从序列尾开始计算的位置。如果切片间隔数为负数,则表示倒序切片。

倒序

由于Slice的存在,python的倒序是比较容易的。

L=L[::-1]

此外,在处理高维数据的时候,还可以使用numpy.flip或tf.reverse。

字符串格式化

目前python的字符串格式化,有两种style:Old Style和New Style。两者的区别详见:

https://pyformat.info/

这里仅给出几个简单示例:

Old Style:'%s %s' % ('one', 'two')

New Style:'{} {}'.format('one', 'two')

New Style还可以这样玩:

'{name} {name} {age}'.format(name='John', age='two')

print("{:.2f}".format(3.1415926))

print("{0: >50}".format(3.1415926))

有了上述的placeholder之后,参数也未必再需要按出现的顺序给了。相同的placeholder设置一次就行了。

还可以这样:

from string import Template
info = dict(Mcap=Mcap, curr=curr)
Template('The market cap of Alibaba is $Mcap mio $curr.')
        .substitute(info)

python3.6引入了f-string:

f'The market cap of Alibaba is {Mcap} mio {curr}.'

python的字符串还有其他玩法:

打印45个=: print('=' * 45)

print('Hello World!'.center(45, '='))

效果:

=================Hello World!================

参考:

https://mp.weixin.qq.com/s/jTiZOazn66nK6CU1SAtpTw

格式化String

https://mp.weixin.qq.com/s/YkV7jdSEkTCSXuotENY3Mg

99%的Python用户都不知道的f-string隐秘技巧

特殊语法:filter、map、reduce、lambda

filter(function, sequence):对sequence中的item依次执行function(item),将执行结果为True的item组成一个List/String/Tuple(取决于sequence的类型)返回。

>>> def f(x): return x % 2 != 0 and x % 3 != 0 
>>> filter(f, range(2, 25)) 
[5, 7, 11, 13, 17, 19, 23]

**map(function, sequence) **:对sequence中的item依次执行function(item),将执行结果组成一个List返回。

>>> def cube(x): return x*x*x 
>>> map(cube, range(1, 11)) 
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

reduce(function, sequence, starting_value):对sequence中的item顺序迭代调用function,如果有starting_value,还可以作为初始值调用,例如可以用来对List求和。

>>> def add(x,y): return x + y 
>>> reduce(add, range(1, 11)) 
55 (PS: 1+2+3+4+5+6+7+8+9+10)

lambda:这是Python支持一种有趣的语法,它允许你快速定义单行的最小函数,类似与C语言中的宏,这些叫做lambda的函数,是从LISP借用来的,可以用在任何需要函数的地方:

>>> g = lambda x: x * 2 
>>> g(3)
6
>>> (lambda x: x * 2)(3) 
6

参考:

http://www.cnblogs.com/longdouhzt/archive/2012/05/19/2508844.html

Python特殊语法:filter、map、reduce、lambda

https://www.zhihu.com/question/20125256

Lambda表达式有何用处?如何使用?

https://mp.weixin.qq.com/s/sBKosZTns_qePiKIYbCd1w

一文搞懂Python匿名函数

defaultdict()和namedtuple()

defaultdict()和namedtuple()是collections模块里面2个很实用的扩展类型。

from collections import defaultdict, namedtuple

defaultdict():返回一个和dictionary类似的对象,和dict不同主要体现在2个方面:

1.可以指定key对应的value的类型。

2.不必为默认值担心,换句话说就是不必担心有key没有value这回事。总会有默认的value。

d = defaultdict(list)

该语句创建一个defaultdict类型(你可以想象为dict类型),value的类型是list。

namedtuple():namedtuple创建一个和tuple类似的对象,而且对象拥有可以访问的属性。这对象更像带有数据属性的类,不过数据属性是只读的。

>>> from collections import namedtuple
>>> TPoint = namedtuple('TPoint', ['x', 'y'])
>>> p = TPoint(x=10, y=10)
>>> p
TPoint(x=10, y=10)
>>> p.x
10
>>> p.y
10

PS:非常类似C语言的结构体,不过数据属性是只读的。

参考:

http://www.cnblogs.com/herbert/p/3468294.html

再谈collections模块defaultdict()和namedtuple()


collections模块还有其他一些功能。例如:

https://mp.weixin.qq.com/s/lHFbec5oBshoASjJQHXxtg

用好collections模块,对李白诗集进行字频统计

@的用法

@在python中是装饰器的意思,它的用法比较复杂。假设我们要增强函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

在python 3.5以后,@是一个操作符,表示矩阵-向量乘法。

A@x就是矩阵-向量乘法np.dot(A, x)

参见:

https://www.zhihu.com/question/26930016

如何理解Python装饰器?

https://mp.weixin.qq.com/s/1QjJqFfJNNych9b6ae5VUg

深入理解Python装饰器

https://www.liaoxuefeng.com/wiki/1016959663602400/1017502538658208

使用@property

https://www.liaoxuefeng.com/wiki/1016959663602400/1017451662295584

装饰器

https://mp.weixin.qq.com/s/qMT46hjOQeXsjVpZPqLRVA

一文读懂Python装饰器

https://mp.weixin.qq.com/s/_ZvF6jK5Jo4rFGwHvEoAig

一文读懂Python装饰器由来

https://mp.weixin.qq.com/s/Wsk6H3Z6HwGPKTRNYc2cLw

一个已经存在10年,却被严重低估的库(decorator)

闭包

在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。

用比较容易懂的人话说,就是当某个函数被当成对象返回时,夹带了外部变量,就形成了一个闭包。

https://mp.weixin.qq.com/s/qYKNGqItnSXq0-Zq2kMCKA

聊一聊Python中的闭包

Fork me on GitHub