zoukankan      html  css  js  c++  java
  • DAY2-Python学习笔记

    1.迭代器:可以直接作用于for循环的对象统称可迭代对象Iterable,使用isinstance()判断一个对象是否是Iterable对象:

    >>> from collections import Iterable
    >>> isinstance([], Iterable)
    True
    >>> isinstance({}, Iterable)
    True
    >>> isinstance('abc', Iterable)
    True
    >>> isinstance((x for x in range(10)), Iterable)
    True
    >>> isinstance(100, Iterable)
    False

    可以被next()函数调用并不断返回下一个值的对象称为迭代器Iterator,使用isinstance()判断一个对象是否是Iterator对象:

    >>> from collections import Iterator
    >>> isinstance((x for x in range(10)), Iterator)
    True
    >>> isinstance([], Iterator)
    False
    >>> isinstance({}, Iterator)
    False
    >>> isinstance('abc', Iterator)
    False

    注意与Iterable 和 Iterator, listdictstr虽然是Iterable,却不是Iterator,转化使用iter()函数:

    >>> isinstance(iter([]), Iterator)
    True
    >>> isinstance(iter('abc'), Iterator)
    True

    2.返回函数和闭包:

    def lazy_sum(*args):
        def sum():
            ax = 0
            for n in args:
                ax = ax + n
            return ax
        return sum

    当我们调用lazy_sum()时,返回的并不是求和结果,而是求和函数

    >>> f = lazy_sum(1, 3, 5, 7, 9)
    >>> f
    <function lazy_sum.<locals>.sum at 0x101c6ed90> 

    内部函数sum可以引用外部函数lazy_sum参数局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”

    3.匿名函数:与Java概念相似

    lambda x: x * x

    关键字lambda表示匿名函数,冒号前面的x表示函数参数。

    4.装饰器:在代码运行期间为已定义好的函数动态增加功能的方式,称之为“装饰器”(Decorator):

    >>> def now():
    ...     print('2015-3-25')

    为其增加打印日志的功能:

    def log(func):
        def wrapper(*args, **kw):
            print('call %s():' % func.__name__)
            return func(*args, **kw)
        return wrapper
    
    @log
    def now():
        print('2015-3-25')

    借助Python的@语法,把log置于函数的定义处,把@log放到now()函数的定义处,相当于执行了语句:now = log(now)

    log()是一个decorator,返回一个函数,原来的now()函数仍存在,只是现在同名的now变量指向了新的函数,于是调用now()将执行新函数,即在log()函数中返回的wrapper()函数。

    wrapper()函数的参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用。在wrapper()函数内,首先打印日志,再紧接着调用原始函数。

    5.偏函数:Python的functools模块提供functools.partial()方法创建一个偏函数:

    def int2(x, base=2):
        return int(x, base)
    >>> int2('1000000')
    64
    >>> int2('1010101')
    85

    使用functools.partial()方法自己定义int2:

    >>> import functools
    >>> int2 = functools.partial(int, base=2)
    >>> int2('1000000')
    64
    >>> int2('1010101')
    85

    6.模块:与Java中的包相同,一个abc.py的文件就是一个名字叫abc的模块

     内建的sys模块为例,编写一个hello的模块:

    #!/usr/bin/env python3  --让这个hello.py文件直接在Unix/Linux/Mac上运行
    # -*- coding: utf-8 -*-  --表示.py文件本身使用标准UTF-8编码
    
    ' a test module '  #--表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;
    
    __author__ = 'Michael Liao'  #--作者名
    
    import sys  #--导入该模块,就可以访问sys模块的所有功能
    
    def test():
        args = sys.argv
        if len(args)==1:
            print('Hello, world!')
        elif len(args)==2:
            print('Hello, %s!' % args[1])
        else:
            print('Too many arguments!')
    
    if __name__=='__main__':
        test()

    最后两行:当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。

    安装第三方模块:通过包管理工具pip完成的:

    第三方库都会在Python官方的pypi.python.org网站注册,安装命令:

    pip install Pillow

    Anaconda,这是一个基于Python的数据处理和科学计算平台,它已经内置了许多非常有用的第三方库,可以尝试直接import numpy等已安装的第三方模块

     

    7.作用域:

    __xxx__:这样的变量是特殊变量,可以被直接引用,但是有特殊用途

    abc:是公开的(public),可以被直接引用

    _xxx__xxx是非公开的(private),不应该被直接引用(Python没有一种方法可以完全限制访问private函数或变量,从编程习惯上不应该引用private函数或变量)

    8.类:

    class Student(object):
        pass

    (object)表示该类是从哪个类继承下来的

    class Student(object):
    
        def __init__(self, name, score):
            self.name = name
            self.score = score

    创建实例的时候__init__()方法可以强制绑定属性,__init__()方法的第一个参数永远是self(指向创建的实例本身)但是创建实例的时候self不需要传

    方法:第一个参数要是self

    由于Python是动态语言,根据类创建的实例可以任意绑定属性。

    9.访问限制:让内部属性不被外部访问,可以把属性的名称前加上两个下划线__变成了一个私有变量(private),与Java相似可在class中设置get和set方法

    10.继承和多态

    继承:

    class Animal(object):
        def run(self):
            print('Animal is running...')
    class Dog(Animal): pass class Cat(Animal): pass

    多态:子类方法覆盖父类方法

    静态语言 vs 动态语言:

    静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法

    Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了:

    class Timer(object):
        def run(self):
            print('Start...')

    这就是动态语言的“鸭子类型”:看起来像鸭子就把它当做鸭子吧!

    11.获取对象信息:

    判断对象类型:type()函数

    判断class的类型:isinstance()函数,两个参数比较是否相同

    获得一个对象的所有属性和方法:dir()函数

    类似__xxx__的属性和方法在Python中都是有特殊用途的:__len__方法返回长度:

    >>> len('ABC')
    3
    >>> 'ABC'.__len__()
    3

    12.实例属性和类属性:

    实例绑定属性的方法:通过self变量

    class Student(object):
        def __init__(self, name):
            self.name = name
    
    s = Student('Bob')
    s.score = 90

    类(class)绑定属性的方法:与Java一样增加类属性

    class Student(object):
        name = 'Student'

    13.使用__slots__ :

    动态语言可以给实例绑定任何属性和方法:

    >>> def set_age(self, age): # 定义一个函数作为实例方法
    ...     self.age = age
    ...
    >>> from types import MethodType
    >>> s.set_age = MethodType(set_age, s) # 给实例绑定一个方法
    >>> s.set_age(25) # 调用实例方法
    >>> s.age # 测试结果
    25

    但是,给一个实例绑定的方法,对另一个实例是不起作用的,__slots__限制实例的属性,在定义class的时候,定义一个特殊的__slots__变量来限制该class实例能添加的属性:

    class Student(object):
        __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称

    >>> s = Student() # 创建新的实例
    >>> s.name = 'Michael' # 绑定属性'name'
    >>> s.age = 25 # 绑定属性'age'
    >>> s.score = 99 # 绑定属性'score'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'Student' object has no attribute 'score'

    注意:__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的

    14.@property:既能检查参数,又可以用类似属性这样简单的方式来访问类的变量,@property装饰器就是负责把方法变成属性调用的:

    class Student(object):
    
        @property
        def get_score(self):
             return self._score
        @score.setter
        def set_score(self, value):
            if not isinstance(value, int):
                raise ValueError('score must be an integer!')
            if value < 0 or value > 100:
                raise ValueError('score must between 0 ~ 100!')
            self._score = value

    把一个getter方法变成属性,只需要加上@property就可以了,@property本身又创建了另一个装饰器@score.setter把一个setter方法变成属性赋值

    还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性:

    class Student(object):
    
        @property
        def birth(self):
            return self._birth
    
        @birth.setter --birth是可读写属性
        def birth(self, value):
            self._birth = value
    
        @property --age就是一个只读属性
        def age(self):
            return 2015 - self._birth

    15.多重继承:与Java不同Python允许多继承

    16.定制类:类似__slots__这种形如__xxx__有特殊用途的函数,可以帮助我们定制类

    详细文档

    __str__:打印好看

    __iter__:用于for ... in循环

    __getitem__:像list那样按照下标取出元素

    __getattr__:动态返回一个属性

    __call__:任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用

    17.枚举类:枚举是列出某些有穷序列集的所有成员,Enum来实现这个功能:

    from enum import Enum
    
    Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

    这样我们就获得了Month类型的枚举类

    更精确地控制枚举类型可以从Enum派生出自定义类:

    from enum import Enum, unique
    
    @unique --@unique装饰器可以帮助我们检查保证没有重复值class Weekday(Enum):
        Sun = 0 # Sun的value被设定为0
        Mon = 1
        Tue = 2
        Wed = 3
        Thu = 4
        Fri = 5
        Sat = 6
  • 相关阅读:
    10 种保护 Spring Boot 应用的绝佳方法
    Redis 如何分析慢查询操作?
    Spring Boot 主类及目录结构介绍
    Redis 再牛逼,也得设置密码!!
    Spring Data Redis 详解及实战一文搞定
    Spring Boot Redis Cluster 实战干货
    超详细的 Redis Cluster 官方集群搭建指南
    Redis Linux 安装运行实战全记录
    hdu 4790 Just Random (思路+分类计算+数学)
    poj 1328 Radar Installation(贪心)
  • 原文地址:https://www.cnblogs.com/xussi/p/9044925.html
Copyright © 2011-2022 走看看