社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

6 个值得玩味的 Python 代码

Python爱好者社区 • 2 年前 • 230 次点击  
来自公众号:Python七号

阅读本文大概需要 3.6 分钟。

先选取了 6 个自己认为值得玩味的 python 代码,希望对正在学习 python 的你有所帮助。

1、类有两个方法,一个是 __new__,一个是 __init__,有什么区别,哪个会先执行呢?

class test(object):
    def __init__(self):
        print("test -> __init__")

    def __new__(cls):
        print("test ->__new__")
        return super().__new__(cls)

a = test()

运行结果如下:

test ->__new__
test -> __init__

再来看另一个例子

class test2(object):
    def __init__(self):
        print("test2 -> __init__")

    def __new__(cls):
        print("test2 ->__new__")
        return object()

b = test2()

运行结果如下:

test2 ->__new__

这里给出官方的解释:__init__ 作用是类实例进行初始化,第一个参数为 self,代表对象本身,可以没有返回值。__new__ 则是返回一个新的类的实例,第一个参数是 cls 代表该类本身,必须有返回值。很明显,类先实例化才能产能对象,显然是 __new__ 先执行,然后再 __init__,实际上,只要 __new__ 返回的是类本身的实例,它会自动调用 __init__ 进行初始化。但是有例外,如果 __new__ 返回的是其他类的实例,则它不会调用当前类的 __init__。下面我们分别输出下对象 a 和对象 b 的类型:

print( type(a))
#

print( type(b))
#

可以看出,a 是 test 类的一个对象,而 b 就是 object 的对象。

参考文档:

https://docs.python.org/3/reference/datamodel.html?highlight=__new__#object.__new__

2、map 函数返回的对象

map()函数第一个参数是 fun,第二个参数是一般是 list,第三个参数可以写 list,也可以不写,作用就是对列表中 list 的每个元素顺序调用函数 fun 。

>>> b=map(lambda x:x*x,[1,2,3])
>>> [i for i in b]
[149]
>>> [i for i in b]
[]
>>>

有没有发现,第二次输出 b 中的元素时,发现变成空了。原因是 map() 函数返回的是一个迭代器,并用对返回结果使用了 yield,这样做的目的在于节省内存。
举个例子:

#encoding:UTF-8  
def yield_test(n):  
    for i in range(n):  
        yield call(i)  
    #做一些其它的事情      

def call(i):  
    return i*2  

#使用for循环  
x = yield_test(5)
print([i for i in x])
print([i for i in x])

执行结果为:

 [02468]
 []

这里如果不用 yield,那么在列表中的元素非常大时,将会全部装入内存,这是非常浪费内存的,同时也会降低效率。

关于迭代器的介绍见前文:python 基础系列--可迭代对象、迭代器与生成器

3、正则表达式中 compile 是否多此一举?

比如现在有个需求,对于文本

中国
,用正则匹配出标签里面的“中国”,其中 class 的类名是不确定的。有两种方法,代码如下:

>>> import re
>>> text = '

中国
'
>>> #方法一
...
>>> re.findall('
(.*)
'
,text)
['中国']
>>> #方法二
...
>>> regex='
(.*)
'

>>> pattern = re.compile(regex)
>>> re.findall(pattern,text)
['中国']
>>>

这里为什么要用 compile 多写两行代码呢?原因是 compile 将正则表达式编译成一个对象,加快速度,并重复使用。

4、[[1,2],[3,4],[5,6]]一行代码展开该列表,得出[1,2,3,4,5,6]

>>> [j for i in [[1,2],[3,4],[5,6]] for j in i]
[123456]
>>>

5、一行代码将字符串 "->" 插入到 "abcdefg"中每个字符的中间

>>> "->".join("abcdef")
'a->b->c->d->e->f'
>>>

这里也建议多使用 os.path.join() 来拼接操作系统的文件路径。

6、zip 函数

zip() 函数在运算时,会以一个或多个序列(可迭代对象)做为参数,返回一个元组的列表。同时将这些序列中并排的元素配对。zip() 参数可以接受任何类型的序列,同时也可以有两个以上的参数;当传入参数的长度不同时,zip 能自动以最短序列长度为准进行截取,获得元组。

>>> a=[1,2]
>>> b=(3,4)
>>> zip(a,b)
0x000001A20201AA08>
>>> for i in zip(a,b):
...     print(i)
...
(13)
(24)
>>> a="ab"
>>> b="xyz"
>>> for i in zip(a,b):
...     print(i)
...
('a''x')
('b''y')
>>>


--- EOF ---


推荐↓↓↓
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/129123
 
230 次点击