Python笔记整理

目录

 

Python的数据类型:

格式化字符串

逻辑运算符

迭代器(iterator)

生成器(generator):一边循环一边计算

函数(Python的函数也是对象)

高阶函数

匿名函数:lambda x

偏函数:设定参数的默认值,降低函数调用的难度

模块化

面向对象编程

     作用域

     继承和多态

 枚举类:Enum

使用元类:

collection:提供例如许多集合类

错误机制

调试

文件/内存读写

协程


Python的数据类型

1.String 字符串类型,不能用索引的方式修改值(用引号)

2.List 列表 相当于数组(用方括号)

3.Tuple 元组;元组的元素不能修改(用圆括号)

4.dict字典(用花括号)

   (1) 字典的键是不可变的,所以key只能为数字,字符串,元组

6.set集合(用花括号)

   (1)与字典相同,但是没有value值,只有key的数组,要求值不能重复,并且无序

类型属于对象,变量是没有类型的

不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。

可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响

格式化字符串

1.str()

2.%       eg: camels = 42    '%s' % camels => '42' 

a, b = 0, 1

a, b = a+b, a+b //右边的表达式会在赋值变动之前执行。右边表达式的执行顺序是从左往右的。

逻辑运算符

(1)and : x and y 如果x为False,返回False,否则返回y的计算值

(2)or: x or y 如果x非0,返回x的值,否则它返回y的计算值

迭代器(iterator)

   (1)迭代器从集合的第一个元素开始访问,直到所有元素都被访问结束。迭代器只能往前不后退。

   (2)iter()和next()

   (3)惰性计算:不执行时,存储的是一个规则,执行时,可以是无限大的数据流,但是列表存储的数据是有限大的。生成器也是可以这样的。

   (4)iterator对象表示的是一个数据流(可以无限大), 可以使用next()获得下一次的计算结果,知道没有数据时跑出StopIteration错误,可以认为这个流并不知道序列的长度,只能通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

   (5) 凡是可作用于for循环的对象都是Iterable类型;

   (6)凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

   (7) 集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

生成器(generator):一边循环一边计算

    生成器的创建方式:(1)将列表生成式的[],换成()     (2)在循环体中使用yield, 

    生成器是一个返回迭代的函数,只能进行迭代操作。相当于生成器的返回值是一个结果的迭代器,记录每次值的变化。 生成器g保存的是算法,每次调用next(g)就计算出g下一个元素的值,或者通过 for n in g:循环调用

函数(Python的函数也是对象)

(1)使用def关键字声明函数

(2)参数传递的方式 4种

            1)位置参数:def power(x)

            2)默认参数:必选参数在前,默认参数在后。默认参数必须指向不变对象,如果对象可变,可能产生错误的结果。

            2)可变参数:在参数名前加一个*,表示函数参数个数可变,这些可变参数会被组装成一个tuple。

                 eg: *args 是可变参数组,是一个元组 fun(*(1,2,3))

            3)关键字参数:在参数名前加**,表示该参数是关键字参数,可以传入一个dict,关键字参数获得输入的一个拷贝,对关键字参数的改变并不影响输入。

                   **kw是关键字参数组,是一个字典  fun(**{'a':1,'b':2})

            4)命名关键字参数:如果需要限制关键字参数的名字,就可以用命名关键字参数,在关键字参数前加*,来隔离其他类型的参数和关键字参数,eg:person(name,age, * ,city,job) // city和job是两个关键字参数

高阶函数

1.变量可以指向函数: f = abs

2.函数名也是变量:abs = 10

3.一个函数可以接收另一个函数作为参数,这种函数就称之为高阶函数

4.函数作为返回值(闭包)

高阶函数举例:

1.iterator map(functionName, iteratable):将function作用于iteratable的每个元素,返回一个迭代器

   functionName:函数变量

   iterable: 被作用的序列

   返回值:一个iterator

2.reduce(functionName(result, nextelement), iteratable):将结果继续和序列的下一个元素做函数为函数的输入运算,返回最终结果

3.filter(functionName, iteratable):将function作用于iteratable的每个元素,根据返回的true or false来决定是否保留该元素

4.sorted(iteratable,key = functionName,reverse ):将function作用于iteratable的每个元素,返回结果作为排序依据,默认从小到大

5.装饰器(decorator):函数仍然存在,但是为原函数添加一些新功能,但不改变原函数功能

   (1)构造一个装饰器,构造器返回一个函数

   (2)使用@语法将装饰器置于函数的定义处

 

匿名函数:lambda x

   1.只能有一个表达式

偏函数:设定参数的默认值,降低函数调用的难度

       functiontools.partial(int, base = 2) 

      =

        def int2(x):

              return int(x, base = 2)

模块化

       一个Python文件,称为模块,一个目录,称为包

       每个包目录下,需要包含一个"__init__.py"文件,否则Python会把它当做普通目录

注意:(1)模块名要遵循Python变量命名规范,不要使用中文、特殊字符;

           (2)模块名不要和系统模块名冲突,最好先查看系统是否已存在该模块,检查方法是在Python交互环境执行import abc,若成功则说明系统存在此模块。

      任何模块代码的第一个字符串都被视为模块的文档注释

变量和函数的公开性:

      正常的函数和变量名是公开的,

      类似__xxx__是特殊变量,可以直接引用,但是有特殊用途。 eg: __author__,__name__

      类似_xxx或__xxx是非公开的,不应该被直接用

      包/模块/函数 = 目录/.py文件/def 

 

面向对象编程

     类和实例

     基类:object

     模板

     class ClassName(parent):

         """docstring for ClassName"""

         def __init__(self, arg):   # 构造函数,self = this,self是成员函数的第一个参数,由Python填入

              super(ClassName, self).__init__()

              self.arg = arg

     self指向创建的实例本身

     作用域

         __xxx__是特殊变量

         _xxx, __xxx是非公开的函数或变量,但_xxx实际是可以被访问的,只是约定俗成的,而__xxx 也可以通过_ClassName__xxx访问【不同的解释器方法不一样】

     继承和多态

          isinstance(instance1,class1); // 判断instance1是不会class1的一个实例

          Python这种动态语言的鸭子类型决定了继承不像静态语言

         鸭子类型【动态类型的一种风格,不是由继承特定的类或实现特定的接口,而是当前的方法和属性的集合决定,鸭子类型中关注的不是对象的类型本身,而是他如何使用。】:

               1、变量绑定的类型具有不确定性

               2、函数可以接收任意类型的参数

               3、调用方法时不检查提供的参数类型

               4、调用是否成功由参数的方法和属性确定

               5、调用不成功抛出错误(也就是对象中没有实现该功能的方法)

       获取对象信息

             type();// 判断对象类型,if(type(fn) == types.FunctionType)

             dir();  // 获得一个对象的所有属性和方法,返回list

             hasattr(obj, attrname); // 判断obj是否有attrname这个属性

      实例属性和类属性

            实例属性/方法【只有在该实例中有效】:

                        (1)通过self变量或通过实例变量

                        (2) MethodType(funcname,args)

            类属性:

                        (1)在类中定义

                        (2)使用类名定义

       限制实例的属性

         (1)__slots__  【不能继承给子类】

                 __slots__ = (attrname1,attrname2,,,,) // 说明属性限制在slots中,不在slots中的不能被定义或者使用。

       隐藏属性

           @property装饰器【将方法变成属性】

           @attrname.getter(attrname的getter函数)

           @attrname.setter (attrname的setter函数)

           因为@property对一个变量只能出现一次。

           这里的attrname是暴露给用户的名称,不允许跟setter和getter函数的属性名相同。否则是递归调用,栈溢出

       多重继承

           class classsName1(pclassName1,pclassName2,....)

           在设计类的继承关系时,通常主线都是单一继承下来的,但是如果需要加入额外的功能,通过多继承就可以实现,这种设计称之为MixIn

      定制类

           __slot__

           __len__():在类中定义,可以使得class调用len()函数

           __str__():用于用户查看实例变量,得到一个字符串化对象【直接print对象时,将调用该函数,如果在交互式模式下,输入对象回车,调用的是__repr__(),并不是__str__()】

           __iter__(self):使得对象可以被迭代,就需要实现该方法,该方法返回一个迭代对象。for循环会调用迭代对象的__next__方法取下一个值,直到遇到StopIteration的错误时。

           __getitem__(self,n):通过下标方式访问对象

           __setitem__():通过下标方式设置对象的属性值

           __delitem__():通过下标方式删除对象的属性值

           __getattr__(self,attr):当使用对象访问一个对象不存在的属性时,将调用该函数【可以使用该函数做一些错误处理】

          __call__(self):实现该函数,可以使得通过对象加()方式调用该函数。【模糊了对象和函数的概念,使得“函数”可以在运行期时被创建】

                   callable(obj):可以判断一个对象是否为“可调用”对象

          __repr__():显示该实例信息

         __add__():+号运算符重载

         __radd__():表示右边相加,允许对象在加号右边

 

 枚举类:Enum

      Month = Enum('Month', ('Jan', 'Feb'))   // 默认从1开始

 

使用元类

   1、使用type()动态创建类

       动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的。

       用type()可以用来得到一个对象的类型,还可以创建出新的类型

       type(classname, 继承的父类集合,class的方法名称与函数绑定 )

            eg: def fn() # 定义函数, Hello = type('Hello', (object,), dict(hello = fn)) # Hello.hello()

   2、用metaclass控制类的创建行为

        先定义metaclass,就可以创建类,最后创建实例

        metaclasas是类的模板,所以必须从type类型派生

 

collection:提供例如许多集合类

   namedtuple(className,attrlist):用来创建一个自定义的tuple对象,className继承了tuple,有attrList不可变

   deque():双向列表

   defaultdict():如果没有key不存在,返回一个默认值

   OrderedDict():key按照插入的顺序排列

   ChainMap():把多个dict组成一个逻辑上的dict

错误机制

    try:

    except xxx as e:

   finally:

    raise ErrorClass()  # 抛出错误

 

调试

    assert 判断语句 语句 # 判断语句为false 就执行后面的语句 

    logging 

    pdb Python调试器,让程序单步执行或设置断点

文件/内存读写

StringIO:对内存读写,操作的对象是字符串类型

ByteIO: 对内存读写,操作对象是二进制数据

pickle包:pickle.load() , pickle.dump() # 反序列化和序列化

 

协程

协程(Coroutine),又称微线程。在Lua等语言中广泛应用。

子程序调用时通过堆栈实现的,一个线程就是执行一个子程序,子程序调用总是一个入口,一次返回。调用顺序是明确的。

协程看上去也是子程序,但执行过程中,在子程序内部可中断,转而执行别的子程序,然后再返回来继续执行。这里的中断并不是通过子程序调用产生的,而是类似于CPU的中断。

相比于多线程,协程优势是:(1)子程序切换不再是线程切换,而是由程序自身控制,因此没有线程切换开销。当线程数越多时,协程的性能优势越明显(2)不需要多线程的锁机制,因为只有一个线程不存在同时写冲突。在协程中控制共享资源不佳锁,只需判断状态就可以了,所以执行效率比多线程高得多。

子程序就是协程的一种特例——Donald Knuth

协程是编译器级,而进程和线程是操作系统级的。

协程本身并不是“异步”的,它不是多线程。

注意:
(1)在输入整数时,以0开头,可能会有奇怪的错误
(2) / 是正常的除,//是整除
(3) 运算符优先级:PEMDAS(括号、指数运算、乘除运算、加减运算)
(4)算术运算不能用于字符串,但是+ 可以,效果是拼接, * 也可以,效果是重复字符串,要求必须与整数相乘
(5)所有放变量名的地方几乎都能放一个表达式,除了赋值语句的左值
(6)堆栈示意图
(7)对象的赋值运算是引用同一个对象,但是基本类型和一些不可变的对象,如字符串。
(8)列表的索引必须是整数,但字典的索引几乎可以是任何类型,字典插入的顺序和存储的顺序不是一一对应的,orderedDict保持插入的顺序
(9) % 当第一个参数是字符串时,%是格式运算符,如果有多个格式序列,则第二个参数要求是元组
(10)对象拷贝object.copy()是浅拷贝,对于嵌套的对象只拷贝了引用。object.deepcopy()是深拷贝

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值