Day 05 python进阶

本文详细介绍了Python的PEP8代码规范,包括import的组织、代码编排、注释编排和命名风格。此外,还讨论了*和**在函数定义中的用法,Python中的赋值和引用,迭代器与生成器的概念及其优缺点,以及装饰器的工作原理和应用场景。文章旨在提升代码质量和可读性。
摘要由CSDN通过智能技术生成

Python进阶鸭
作为新手小白,代码写的好不好先不说,但是必须要规范,给前辈留下好的印象

PEP8代码规范
- import:
模块内容的顺序:import部分,又按标准、三方和自己编写顺序依次排放,之间空一行。
不要在一句import中多个库,比如import os, sys不推荐。
如果采用from XX import XX引用库,可以省略‘module.’。若是可能出现命名冲突,这时就要采用import XX,尽量不要使用from xx import *.
- 代码编排:
缩进。优先使用4个空格的缩进(编辑器都可以完成此功能),其次可使用Tap,但坚决不能混合使用Tap和空格。
每行最大长度79,换行可以使用反斜杠,最好使用圆括号。换行点要在操作符的后边敲回车。
类和top-level函数定义之间空两行;类中的方法定义之间空一行;函数内逻辑无关段落之间空一行;其他地方尽量不要再空行。
- 注释编排:
最忌讳逐行加注释,也忌讳没有一个注释,也有总体原则,错误的注释不如没有注释。所以当一段代码发生变化时,第一件事就是要修改注释!避免无谓的注释
注释必须使用英文,最好是完整的句子,首字母大写,句后要有结束符,结束符后跟两个空格,开始下一句。如果是短语,可以省略结束符。
行注释:在一句代码后加注释,但是这种方式尽量少使用。
块注释:在一段代码前增加的注释。在‘#’后加一空格。段落之间以只有‘#’的行间隔。
- 命名风格:
中心思想就是见名思意,让人家知道是干啥的,除非在lambda函数中,否则不要用单字母的变量名(即使是lambda函数中的变量名也应该尽可能的有意义)
尽量以免单独使用小写字母’l’,大写字母’O’,以及大写字母’I’等容易混淆的字母。
模块命名尽量短小,使用全部小写的方式,可以使用下划线。
包命名尽量短小,使用全部小写的方式,不可以使用下划线。
类名、异常名使用CapWords的方式,模块内部使用的类采用_CapWords的方式。
异常命名使用CapWords+Error后缀的方式。
全局变量尽量只在模块内有效,类似C语言中的static。实现方法有两种,一是__all__机制;二是前缀一个下划线。对于不会发生改变的全局变量,使用大写加下划线。
函数命名使用全部小写的方式,可以使用下划线。
常量命名使用全部大写的方式,可以使用下划线。
类的属性(方法和变量)命名使用全部小写的方式,可以使用下划线。
内部使用的类、方法或变量前,需加前缀’_'表明此为内部使用的。虽然如此,但这只是程序员之间的约定而非语法规定,用于警告说明这是一个私有变量,外部类不要去访问它。但实际上,外部类还是可以访问到这个变量。import不会导入以下划线开头的对象。
类的属性若与关键字名字冲突,后缀一下划线,尽量不要使用缩略等其他方式。
双前导下划线用于命名class属性时,会触发名字重整;双前导和后置下划线存在于用户控制的名字空间的"magic"对象或属性。
为避免与子类属性命名冲突,在类的一些属性前,前缀两条下划线。比如:类Foo中声明__a,访问时,只能通过Foo._Foo__a,避免歧义。如果子类也叫Foo,那就无能为力了。
类的方法第一个参数必须是self,而静态方法第一个参数必须是cls。
一般的方法、函数、变量需注意,如非必要,不要连用两个前导和后置的下线线。两个前导下划线会导致变量在解释期间被更名。两个前导下划线会导致函数被理解为特殊函数,比如操作符重载等。
**Python中 * 和 的区别

  • 函数定义
def foo(*args,**kwargs):
     pass

Python中,( *)会把接收到的参数形成一个元组,而( ** )则会把接收到的参数存入一个字典
我们可以看到,foo方法可以接收任意长度的参数,并把它们存入一个元组中
eg(**)将接收到的参数存入一个字典
在这里插入图片描述
( * )和( ** )一起使用 
在这里插入图片描述
Python的赋值和引用
== ,is : ==判断的是值,is判断的是内存地址(即对象的id)
Python的迭代器与生成器
迭代器
迭代是Python最强大的功能之一,是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。迭代器有两个基本的方法:iter() 和 next()。字符串,列表或元组对象都可用于创建迭代器:在这里插入图片描述
迭代器对象可以使用常规for语句进行遍历:
在这里插入图片描述
生成器
在 Python 中,使用了 yield 的函数被称为生成器(generator)。跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。调用一个生成器函数,返回的是一个迭代器对象。
以下实例使用 yield 实现斐波那契数列:
在这里插入图片描述
生成器的优点:代码实现更加简洁,可以提高代码的可读性。同时当然也具有迭代器的优点,大量数据遍历时内存占用少。

注意
生成器一定是迭代器,但是迭代器不一定是生成器,因为创建一个迭代器只需要实现iter和next()方法就可以了,并不一定要使用yield实现。
生成器的唯一注意事项就是:生成器只能遍历一次。
什么是装饰器?
python装饰器(fuctional decorators)就是用于拓展原来函数功能的一种函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能。
这个函数的特殊之处在于它的返回值也是一个函数,这个函数是内嵌“原“”函数的函数。
一般而言,我们要想拓展原来函数代码,最直接的办法就是侵入代码里面修改,例如:

import time
def f():
    print("hello")
    time.sleep(1)
    print("world")

这是我们最原始的的一个函数,然后我们试图记录下这个函数执行的总时间,那最简单的做法就是改动原来的代码:

import time
def f():
    start_time = time.time()
    print("hello")
    time.sleep(1)
    print("world")
    end_time = time.time()

    execution_time = (end_time - start_time)*1000
    print("time is %d ms" %execution_time)

但是实际工作中,有些时候核心代码并不可以直接去改,所以在不改动原代码的情况下,我们可以再定义一个函数。(但是生效需要再次执行函数)

import time

def deco(func):
    start_time = time.time()
    f()
    end_time = time.time()
    execution_time = (end_time - start_time)*1000
    print("time is %d ms" %execution_time)

def f():
    print("hello")
    time.sleep(1)
    print("world")

if __name__ == '__main__':

    deco(f)
    print("f.__name__ is",f.__name__)
    print() 

这里我们定义了一个函数deco,它的参数是一个函数,然后给这个函数嵌入了计时功能。但是想要拓展这一千万个函数功能,

就是要执行一千万次deco()函数,所以这样并不理想!接下来,我们可以试着用装饰器来实现,先看看装饰器最原始的面貌。

import time

def deco(f):
    def wrapper():
        start_time = time.time()
        f()
        end_time = time.time()
        execution_time = (end_time - start_time)*1000
        print("time is %d ms" %execution_time )
    return wrapper

@deco
def f():
    print("hello")
    time.sleep(1)
    print("world")

if __name__ == '__main__':
    f()

这里的deco函数就是最原始的装饰器,它的参数是一个函数,然后返回值也是一个函数。

其中作为参数的这个函数f()就在返回函数wrapper()的内部执行。然后在函数f()前面加上@deco,

f()函数就相当于被注入了计时功能,现在只要调用f(),它就已经变身为“新的功能更多”的函数了,

(不需要重复执行原函数)。
扩展1:带有固定参数的装饰器

import time

def deco(f):
    def wrapper(a,b):
        start_time = time.time()
        f(a,b)
        end_time = time.time()
        execution_time = (end_time - start_time)*1000
        print("time is %d ms" % execution_time)
    return wrapper

@deco
def f(a,b):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b))

if __name__ == '__main__':
    f(3,4)

扩展2:无固定参数的装饰器

import time

def deco(f):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        f(*args, **kwargs)
        end_time = time.time()
        execution_time_ = (end_time - start_time)*1000
        print("time is %d ms" %execution_time)
    return wrapper


@deco
def f(a,b):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b))

@deco
def f2(a,b,c):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b+c))


if __name__ == '__main__':
    f2(3,4,5)
    f(3,4)

扩展3:使用多个装饰器,装饰一个函数

import time

def deco01(f):
    def wrapper(*args, **kwargs):
        print("this is deco01")
        start_time = time.time()
        f(*args, **kwargs)
        end_time = time.time()
        execution_time = (end_time - start_time)*1000
        print("time is %d ms" % execution_time)
        print("deco01 end here")
    return wrapper

def deco02(f):
    def wrapper(*args, **kwargs):
        print("this is deco02")
        f(*args, **kwargs)

        print("deco02 end here")
    return wrapper

@deco01
@deco02
def f(a,b):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b))


if __name__ == '__main__':
    f(3,4)

结果是:


this is deco01
this is deco02
hello,here is a func for add :
result is 7
deco02 end here
time is 1003 ms
deco01 end here

今日总结如下:又是一天
加油照哥!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值