Python 知识点记录(2020)

0. python 一切执行“左闭右开”

  • range
  • 切片

1. count()、max()

  • count:str.count(sub, start= 0,end=len(string))
    count() 方法用于统计字符串里某个字符出现的次数。

  • max :max(iterable, *[, default=obj, key=func]) -> value
    max 为 python 自带的函数。

    默认情况,结果返回可迭代的对象中最大的那个;

    lst = [1,1, 2,3,4,5]
    max(lst)
    
    5
    

    如要在比较之前修改对象或基于特定属性/索引进行比较,必须使用关键参数key

    lst = [1,1, 2,3,4,5]
    max(lst, key=lambda v: lst.count(v))
    
    1
    

2. lambda

  • 匿名函数语法:lambda argument_list: expression

由于def语句复合语句,它们不能用于需要表达式的地方,这就是为什么有时使用lambda的原因。

注意,lambda等同于你在一个def的return语句中。因此,不能在lambda中使用语句,只允许表达式

3. 什么时候用 for 循环,什么时候用while ,如何考虑?

  • for循环主要用在迭代可迭代对象的情况。

  • while 循环主要用在需要满足一定条件为真,反复执行的情况。

    (死循环+break 退出等情况。)

  • 部分情况下,for 循环和while 循环可以互换使用。

4. class:属性和方法设计之初的目的/原因?以及装饰器的作用?

(1)关于类:类是模板,而实例则是根据类创建的对象。

(2) 属性:类的属性是用来表明这个类是什么。

属性分为:类属性、实例属性

实例属性用于区分不同的实例;
类属性是每个实例的共有属性。

  • 实例属性
    实例属性的创造依靠 __init__() 方法:

    class Circle(object):
       def __init__(self, r):
           self.r = r
    

    类中特殊的 init() 方法,当创建实例时,init() 方法被自动调用为创建的实例增加实例属性。

    面试喜欢问的问题:创建类时,类方法中的self是什么?
    self 代表类的实例,是通过类创建的实例 (注意,在定义类时这个实例我们还没有创建,它表示的我们使用类时创建的那个实例)

  • 类属性
    如果在类上绑定属性,则所有实例都可以访问该类的属性,并且所有实例访问的类属性都是同一个!

    class Circle(object):
       pi = 3.14  # 类属性
    

(3)方法:方法是表明这个类用是来做什么。

在类的内部,使用 def 关键字来定义方法,与一般函数定义不同,类方法必须第一个参数为 self, self 代表的是类的实例(即你还未创建类的实例),其他参数和普通函数是完全一样。

class Circle(object):
   pi = 3.14  # 类属性

   def __init__(self, r):
       self.r = r  # 实例属性

   def get_area(self):
       """ 圆的面积 """
       # return self.r**2 * Circle.pi # 通过实例修改pi的值对面积无影响,这个pi为类属性的值
       return self.r**2 * self.pi  # 通过实例修改pi的值对面积我们圆的面积就会改变

circle1 = Circle(1)
print(circle1.get_area())  # 调用方法 self不需要传入参数,不要忘记方法后的括号  输出 3.14

在方法的内部需要调用实例属性采用 "self.属性名 " 调用。

(4)有了装饰器可以使用 " .属性名 " 获得返回只读属性,而不是必须在类中定义方法再通过 " .属性名( ) " 这种函数调用的方法。

In [101]: class Book(object):
     ...:     def __init__(self,name,sale):
     ...:         self.__name = name
     ...:         self.__sale = sale
     ...:     @property
     ...:     def name(self):
     ...:         return self.__name

In [102]: a_book = Book('magic_book',100000)

In [103]: a_book.name
Out[103]: 'magic_book'

5. 赋值、引用、深拷贝、浅拷贝

(0)赋值:只是复制了对象的引用
例如,b = a ,这种情况下,b和a是一样的,他们指向同一片内存,b不过是a的别名,是引用。(里面的元素是一个东西

赋值操作(包括对象作为参数、返回值)不会开辟新的内存空间,它只是复制了新对象的引用。 也就是说,除了b这个名字以外,没有其它的内存开销。

修改了a,就影响了b;同理,修改了b就影响了a。

(1) 浅拷贝:只拷贝第一层

  • 对不可变对象进行浅拷贝,相当于深拷贝

  • 对可变对象进行浅拷贝,直接修改一个不会影响另一个,但对其可变子元素的修改会影响另一个。例如,列表中嵌套列表的修改则会影响。

    浅拷贝有三种形式:切片操作,工厂函数,copy模块中的copy函数。比如对上述a:

    1、切片操作:b = a[:] 或者 b = [each for each in a]
    2、工厂函数:b = list(a)
    3、copy函数:b = a.copy(a)

(2)深拷贝:copy.deepcopy()

  • 深拷贝得到的对象和原对象互不相干,修改一个不会影响另一个,这里指任何修改

    深拷贝只有一种形式,copy模块中的deepcopy函数。

注:copy() 方法,有copy,copy() 和copy.deepcopy()—— 前者是浅拷贝,后者是深拷贝

浅复制是用copy,只复制父对象,不复制对象内部的子对象;深复制用deepcopy,完全复制父对象和子对象。

一句话再总结:

  • 除了deepcopy都是浅拷贝,只有第一层的浅拷贝修改之后不会改变初始对象;
  • 对 deepcopy后的对象进行的操作,都不再影响初始对象。

6. 如何自己写一个不能被直接 import 访问的模块(_下划线开头)?

  • 如何写一个 module,保存到本地并加载?

  • 如何在线写一个module并加载?

7. 如何使用 print 打印出想要的形状/格式?

真正了解 print()函数:

print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file:  a file-like object (stream); defaults to the current sys.stdout.
sep:   string inserted between values, default a space.
end:   string appended after the last value, default 
  • 参数 sep=’ ’ ,代表不同值之间的间隔,默认为一个空格;也可以自己设定
print('good'"morning")
print('good', 'morning', sep=' ')
  • 参数 end=’\n’,代表print完成一次打印下一次打印之前自动换行;也可以自己设定,比如 end = ‘ ’ ,表示不换行而以一个空格衔接

所以, print()可以直接表示换行操作

例子:99乘法表

for i in range(1, 10):
    for j in range(1, i+1):
        print("{}*{}={}".format(j, i, j*i), end=' ')
    print()
1*1=1 
1*2=2 2*2=4 
1*3=3 2*3=6 3*3=9 
1*4=4 2*4=8 3*4=12 4*4=16 
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81 

注:也可以使用 end=’\t’

8. if name=='main’的作用?

作用:使得 python 脚本只能在命令行运行,而不能被导入当做模块使用。

if __name__=='__main__':
    test()
  • 当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__

  • 而如果在其他地方导入(import)该hello模块时,if判断将失败

因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试

廖雪峰-模块

注意:import 导入Python模块不起作用!!

一个python文件通常有两种使用方法,第一是作为脚本直接执行,第二是 import 到其他的 python 脚本中被调用(模块重用)执行。因此 if __name__ == 'main': 的作用就是控制这两种情况执行代码的过程,在 if __name__ == 'main': 下的代码只有在第一种情况下(即文件作为脚本直接执行)才会被执行,而 import 到其他脚本中是不会被执行的。

注意:__name__ 不带引号!!!

9. 类中object是什么意思?

使得新建的类继承了object对象,拥有了许多可操作的对象,这些都是类中的高级特性。(针对 Python 2)

在 Python 3 中已经默认就帮你加载了object了(即便你没有写上object)。


根据LEGB原则,其中最后一个B原则就是内置(built-in)命名空间,

它会将python内部的__builtin__.py实例化的内容进行检索. 什么意思呢? 这里先列出一段简短的代码。

# -.- coding:utf-8 -.-
# __author__ = 'zhengtong'


class Person(object):
    name = "zhengtong"


if __name__ == "__main__":
    x = Person()

通过这段代码,当我们实例化Person()这个类的时候,那x就是一个实例对象, 整个过程python除了创建Person这个类的命名空间之外(把name=”zhengtong”加入到命名空间中),还会去执行__builtin__.py中的object类,并将object类中的所有方法传承给Person(也就是说Person继承了object的所有方法)。

10. 类中特殊方法,比如__init__的作用?

在刷 leetcode 时发现,所有的 Solution 类都没有用到类的特殊函数,因此产生疑问。
拿 构造函数 init 来说,在类中定义init()方法,是为了方便创建实例的时候给实例绑定上属性,也方便类中的方法(函数)的定义。

比如定义一个矩形的类,目的是求周长和面积:

class Rectangle():
    def getPeri(self,a,b):
        return (a + b)*2
    def getArea(self,a,b):
        return a*b

rect = Rectangle()
print(rect.getPeri(3,4))
print(rect.getArea(3,4))
print(rect.__dict__)

14
12
{}

从上例中可以看到,我们在类中并没有定义init()方法,但是也能够得到类似的要求,结果返回了矩形实例rect的周长及面积。
但是,我们通过print(rect.dict)来看这个实例的属性,竟然是空的,我定义了一个矩形,按理来说它的属性应该是它的长、宽。但是它竟然没有。这就是没有定义init()的结果。

并且,在实例化对象的时候,rect = Rectangle()参数为空,没有指定a、b的值,只有在调用函数的时候才指定了。且类中定义的每个方法的参数都有a、b,这显然浪费感情,在类中直接指定方法就可以了。

上述同样的例子,采用init()方法定义类,如下:

class Rectangle():
    def __init__(self,a,b):
        self.a = a
        self.b = b
    def getPeri(self):
        return (self.a + self.b)*2
    def getArea(self):
        return self.a * self.b

rect = Rectangle(3,4)
print(rect.getPeri())
print(rect.getArea())
print(rect.__dict__)

14
12
{'a': 3, 'b': 4}

定义完init()后,创建的每个实例都有自己的属性,也方便直接调用类中的函数。

11. 返回列表中最值的索引

lst = [40,100,1,3]

def minIndex(lst):
    return min(range(len(lst)),key=lst.__getitem__)

def maxIndex(lst):
    return max(range(len(lst)),key=lst.__getitem__)

print(minIndex(lst))
print(maxIndex(lst))

2
1

12. 函数参数传递:***

这两种用法其实都是用来将任意个数的参数导入到 Python 函数中:

  • 单星号(*):*agrs

    将所有参数以元组(tuple)的形式导入

    def foo(param1, *param2):
        print (param1)
        print (param2)
    foo(1,2,3,4,5)
    
    1
    (2, 3, 4, 5)
    
  • 双星号(**):**kwargs

    双星号()将参数以字典**的形式导入

    def bar(param1, **param2):
        print (param1)
        print (param2)
    bar(1,a=2,b=3)
    
    1
    {'a': 2, 'b': 3}
    

13. logging.warning(“Test wav file play start …”)

学会使用 logging 模块来记录日志,而不是通过print()函数

先挖坑:Python 中 logging 模块的基本用法

参考:

  1. python 60 天精进
  2. Python入门 类class 基础篇
  3. Python中关于对象复制有三种类型的使用方法
  4. python的class(类)中的object是什么意思?
  5. python学习——类中为什么要定义__init__()方法
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值