Python入门总结

参考文献:
https://www.liaoxuefeng.com
http://www.runoob.com

文章目录

  • 1.基础
    • 1.1.变量、基本数据类型
    • 1.2.函数
      • 1.2.1 函数返回值
      • 1.2.2 默认参数
      • 1.2.3 常用函数
      • 1.2.4 返回函数与闭包
      • 1.2.5 匿名函数与 lambda
      • 1.2.5 函数装饰器
      • 1.2.6 functools与偏函数
    • 1.3 异常处理
  • 2 模块、包、类
    • 2.1 模块
    • 2.2 包
    • 2.3 类
      • 2.3.1 关于Python 类
    • 3. io

1.基础

1.1.变量、基本数据类型

(1)数据类型

Python支持多种数据类型,在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对象的,对变量赋值就是把数据和变量给关联起来。Number类型也是对象,且是不可变对象。

常见的不可变对象:数字型量,string,tuple

另外,函数名也是变量,是指向函数的变量

特殊变量命名

  • __xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途
  • _xxx__xxx这样的函数或变量就是非公开的(private),不应该被直接引用(但是也能引用到,但是不推荐)

(2)列表切片、列表生成式

列表切片:取列表中的特定片段

列表生成式:把要生成的元素x * x放到前面,后面跟for循环。例如:[x * x for x in range(1, 11) if x % 2 == 0]

(3)生成器

动态生成元素,访问元素通过next函数进行访问。

 g = (x * x for x in range(10))
 next(g)


#或是通过循环:
for n in g:
   print(n)

复杂的生成器:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b   #每次执行到这里返回。再次执行时从上次返回的yield语句处继续执行
        a, b = b, a + b
        n = n + 1
    return 'done' #执行到return,标识迭代结束,结束时,抛出StopIteration异常,可通过捕获异常,从异常中的value字段获取返回值

(4)关键字

  • yield:用户生成器中;
  • lambda:即匿名函数,不用想给函数起什么名字
  • finally:异常处理
  • is :两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相
  • not:表示逻辑‘非’
  • pass:语句占位符

1.2.函数

1.2.1 函数返回值

函数可以同时返回多个值,但其实就是一个tuple

def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny

1.2.2 默认参数

关于默认参数,需要注意:

  • 必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
  • 如何设置默认参数
  • 默认参数必须指向不变对象。因为默认参数也是一个变量,每次调用该函数,如果改变了默认参数的内容,则下次调用时,默认参数的内容就变了

1.2.3 常用函数

(1) map :Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。

def f(x):
    return x*x
print map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])

(2) reduce : reduce() 函数会对参数序列中元素进行累积。

>>>def add(x, y) :            # 两数相加
...     return x + y
... 
>>> reduce(add, [1,2,3,4,5])   # 计算列表和:1+2+3+4+5
15
>>> reduce(lambda x, y: x+y, [1,2,3,4,5])  # 使用 lambda 匿名函数
15

(3)filter : 用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。

def is_odd(n):
    return n % 2 == 1
 
newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(newlist)

(4) len :获取序列长度
(5) max ,min:返回序列中最大最小值
(6)callable(obj) : 查看一个obj是不是可以像函数一样调用
(7)dir(obj) :查看obj的name space中可见的name
(8)getattr(obj,name) 得到一个obj的name space中的一个name
(8)setattr(obj,name,value) 为一个obj的name space中的一个name指向vale这个object
(9)delattr(obj,name) 从obj的name space中删除一个name
type(obj) 查看一个obj的类型
(10)isinstance(obj,cls) 查看obj是不是cls的instance
(11)issubclass(subcls,supcls) 查看subcls是不是supcls的子类
(12)类型转化:chr, ord, oct, hex, str , list ,tuple, dict, int , float, long
(13)数学运算:divmod , pow, round

1.2.4 返回函数与闭包

函数不仅可以返回普通值,还可以作为返回值。

如果在一个内部函数里对外部作用域(但不是全局作用域)的变量进行引用,内部函数称为闭包(closure)

>>> def lazy_calc_sum(num_list):
    def calc_sum():
        s = 0
        for i in num_list:
            s += i
        return s
    return calc_sum

在上面的例子中,我们在函数lazy_clac_sum中又定义了函数calc_sum,并且,内部函数calc_sum可以引用外部函数lazy_calc_sum的参数和局部变量,当lazy_calc_sum返回函数calc_sum时,相关参数和变量都保存在返回的函数中。

在使用闭关时,需要注意:由于内部函数没有执行,所以所引用的外部变量不会释放,还会保存。这个外部变量的修改会影响后续的调用执行情况(这些返回函数都引用这同一个外部变量)

例如:

def count():
    fs = []  
    for i in range(1,4):
        def g(a):  
            f = lambda : a*a
            return f
        fs.append(g(i))  
    return fs

f1,f2,f3 =count()

def count():
    fs = []   #函数列表
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f) # 循环结束后,fs中存放了三个函数变量,这三个函数变量都引用了变量i。函数的执行是计算i*i。由于直接引用同一个变量,则执行结果都是一致的

    return fs 

f1, f2, f3 = count()

print( f1() )
print( f2() )
print( f3() )

因此,我们应尽量避免在闭包中引用循环变量,或者后续会发生变化的变量。

1.2.5 匿名函数与 lambda

匿名函数类似与:lambda x : exp(x)
关键字lambda表示匿名函数,冒号前面的x表示函数参数。
匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

1.2.5 函数装饰器

装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能

python 函数装饰器类似于Java中的标注。

from functools import wraps

def decorator_name(f):
  # 调用functools.wraps修饰decorated函数,使得被修饰的函数能保持自己的__name__等信息。也
  #可以不使用
    @wraps(f) 
    def decorated(*args, **kwargs):
        if not can_run:
            return "Function will not run"
        return f(*args, **kwargs)
    return decorated
 
@decorator_name   #使用装饰器修改func函数
def func():
    return("Function is running")
 
can_run = True
print(func())
# Output: Function is running
 
can_run = False
print(func())
# Output: Function will not run

1.2.6 functools与偏函数

给函数常用的参数值设定为参数的默认值,可以降低函数调用的难度。偏函数也可以做到这一点。

functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

1.3 异常处理

Python 异常继承体系
https://blog.csdn.net/gaoxin12345679/article/details/47017483
Python入门总结_第1张图片

Python入门总结_第2张图片

完整的异常处理格式:

try:
      XXXX #可能发生异常的语句
 except 
      print("异常处理")
 else
       print('try内代码块没有异常则执行我')
 finally:
        print('无论异常与否,都会执行该模块,通常是进行清理工作')

主动抛出异常:

raise [Exception [, args [, traceback]]]

自定义异常

class XXException(BaseException):
    def __init__(self,msg):
        self.msg=msg
    def __str__(self):
        return self.msg

2 模块、包、类

2.1 模块

https://www.cnblogs.com/kex1n/p/5977051.html

模块,在Python可理解为对应于一个文件。在创建了一个脚本文件后,定义了某些函数和变量。你在其他需要这些功能的文件中,导入这模块,就可重用这些函数和变量。

模块属性__name__,它的值由Python解释器设定。如果脚本文件是作为主程序调用,其值就设为__main__,如果是作为模块被其他文件导入,它的值就是其文件名

模块可以导入其他的模块。通常将import语句放在模块的开头,被导入的模块名字放在导入它的模块的符号表中。

模块搜索路径
当导入一个模块时,解释器先在当前包中查找模块,若找不到,然后在内置的built-in模块中查找,找不到则按sys.path给定的路径找对应的模块文件(模块名.py)

sys.path的初始值来自于以下地方:

  • 包含脚本当前的路径,当前路径
  • PYTHONPATH
  • 默认安装路径

模块能像包含函数定义一样,可包含一些可执行语句。这些可执行语句通常用来进行模块的初始化工作。这些语句只在模块第一次被导入时被执行。这非常重要,有些人以为这些语句会多次导入多次执行,其实不然。

模块在被导入执行时,python解释器为加快程序的启动速度,会在与模块文件同一目录下生成.pyc文件。我们知道python是解释性的脚本语言,而.pyc是经过编译后的字节码,这一工作会自动完成,而无需程序员手动执行。

2.2 包

通常包总是一个目录,可以使用import导入包,或者from + import来导入包中的部分模块。包目录下为首的一个文件便是 __init__.py。然后是一些模块文件和子目录,假如子目录中也有 __init__.py 那么它就是这个包的子包了。

在创建许许多多模块后,我们可能希望将某些功能相近的文件组织在同一文件夹下,这里就需要运用包的概念了。包对应于文件夹,使用包的方式跟模块也类似,唯一需要注意的是,当文件夹当作包使用时,文件夹需要包含__init__.py文件,主要是为了避免将文件夹名当作普通的字符串__init__.py的内容可以为空,一般用来进行包的某些初始化工作或者设置__all__值,__all__是在from package-name import *这语句使用的,全部导出定义过的模块。

python包是:

  • 包是一个有层次的文件目录结构,它定义了由n个模块或n个子包组成的python应用程序执行环境。
  • 通俗一点:包是一个包含__init__.py 文件的目录,该目录下一定得有这个__init__.py文件和其它模块或子包。

2.3 类

定义方式:

class Student(object):#括号中的是父类,括号后面有一个分号

    def __init__(self, name, score):  # 类实例方法:和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self
        self.name = name
        self.score = score

类变量、类成员变量

class Member():
    num=0 #类变量,可以直接用类调用,或用实例对象调用
    def __init__(self,x,y):
        self.x=x  #实例变量(成员变量),需要它是在类的构造函数内以self.开头来定义的

(1)类实例变量:成员变量一定是以self.的形式给出的,因为self的含义就是代表实例对象;
(2)类变量:在类定义下直接声明定义的

特殊变量:

(1)__XX:标识私有变量(private),只有内部可以访问,外部不能访问
(2)__XX__ :特殊变量,特殊变量是可以直接访问的
(3)__slots__ 变量:限制该class实例能添加的属性,仅对当前类实例起作用,对继承的子类是不起作用的

类实例方法、类方法、静态方法

class Foo(object):  
    def test(self)://定义了实例方法  ,第一个参数必须是实例对象,该参数名一般约定为“self”
        print("object")  
 
    @classmethod  
    def test2(clss)://定义了类方法,第一个参数必须是当前类对象,该参数名一般约定为“cls”
        print("class")  
 
    @staticmethod  
    def test3()://定义了静态方法,参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法
        print("static")  

(1)类实例方法:默认的形式,只能由实例对象调用,第一个参数必须是实例对象,该参数名一般约定为“self”。只能由实例对象调用

(2)类方法:通过@classmethod装饰器定义,第一个参数必须是当前类对象,该参数名一般约定为“cls”。实例对象和类对象都可以调用

(3)静态方法:通过@staticmethod装饰器定义,参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法。实例对象和类对象都可以调用。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。

特殊方法
(1)__str__
(2)__iter__
(3)__getitem__
(4)__getattr__
(5)__call__
(6)__init__

关于元类

http://python.jobbole.com/88795/

类也是对象,名字就是类名。这个对象(类)自身拥有创建对象(类实例)的能力,而这就是为什么它是一个类的原因。但是,它的本质仍然是一个对象,于是你可以对它做如下的操作:

  • 你可以将它赋值给一个变量, 你可以拷贝它, 你可以为它增加属性, 你可以将它作为函数参数进行传递。

因为类也是对象,你可以在运行时动态的创建它们,就像其他任何对象一样。首先,你可以在函数中创建类,使用class关键字即可。

元类就是类的类。函数type实际上是一个元类。type就是Python在背后用来创建所有类的元类。现在你想知道那为什么type会全部采用小写形式而不是Type呢?好吧,我猜这是为了和str保持一致性,str是用来创建字符串对象的类,而int是用来创建整数对象的类。type就是创建类对象的类。你可以通过检查__class__属性来看到这一点。Python中所有的东西,注意,我是指所有的东西——都是对象。这包括整数、字符串、函数以及类。它们全部都是对象,而且它们都是从一个类创建而来。

2.3.1 关于Python 类

(1)接口

python没有定义接口的关键字。定义接口只是一个人为规定,在编程过程自我约束。一般来说,以I开头的类视为接口。

class IOrderRepository:
 
    def fetch_one_by(self,nid):
        raise Exception('子类中必须实现该方法')

(2) 多继承

Python支持多继承

class C(A,B):
 def __init__(self):
    pass

注意:python中使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承,也叫菱形继承问题)等。

(3)关于抽象类与抽象方法:

抽象类是包含抽象方法的类,而抽象方法不包含任何可实现的代码,只能在其子类中实现抽象函数的代码。

定义抽象类与抽象方法:
从abc模块调用类abstractmethod和类ABCMeta,自己定义类Foo,继承抽象类ABCMeta,在类Foo中定义exec方法,并添加装饰器abcstractmethod。定义类A继承类Foo,并实例化对象obj,类A中必须有类Foo中的方法否则就会抛出异常。

from abc import abstractmethod,ABCMeta
 
class Foo(metaclass=ABCMeta):
    @abcstractmethod
    def exec(self):
        pass
 
class A(Foo):
    pass
obj=A()

或是通过指定元类:


import abc 
class A(object):
    __metaclass__ = abc.ABCMeta #指定元类
    @abc.abstractmethod
    def load(self, input):
        return
    @abc.abstractmethod
    def save(self, output, data):
        return

3. io

https://www.cnblogs.com/Commence/p/5587995.html

读写文件是最常见的IO操作。python内置了读写文件的函数。

读写文件就是请求操作系统打开一个文件对象通常称为文件描述符,然后,通过操作系统提供的借口从这个文件中读取数据,或者把数据写入这个文件对象

基本处理模式一:

try:
    f = open('/path/to/file', 'r')
    print(f.read())
finally:
    if f:
        f.close()
但是每次都这么写实在太繁琐,

基本处理模式二:

with open('/path/to/file', 'r') as f:
    print(f.read())

file-like Object
像open()函数返回的这种有个read()方法的对象,在Python中统称为file-like Object。除了file外,还可以是内存的字节流,网络流,自定义流等等。file-like Object不要求从特定类继承,只要写个read()方法就行。

StringIO就是在内存中创建的file-like Object,常用作临时缓冲。

你可能感兴趣的:(python)