python入门到跑库

基本语法

1> Python是什么?

  • Python是一个面向对象的解释型的交互式高级脚本语言:Python被设计成一种高可读性的语言,因为它大量地使用了英语中的单词作为关键字,而且不像其他语言使用标点符号构成复杂的语法结构,Python的语法结构非常少。
  • Python是一种面向对象的语言:即Python是支持面向对象的,支持在对象中进行代码封装。
  • Python是一种解释型语言:即Python程序是在运行时由解释器解释执行的,因而不用事先编译源程序。这一点和Perl和PHP类似。
  • Python是一种交互式语言:即你能够在Python提示符下直接交互式地编写你的程序。
  • Python是初学者的语言:Python是一种非常适合初学者的语言,它支持多种类型的应用程序的开发,如简单的文本处理、www浏览器应用程序开发、游戏开发等等。

2> Python的优缺点?

Python是一种面向对象的解释性的交互式语言,带有对象、模块、线程、异常和内存自动管理的机制。
使用Python的优点有:简单、易学、轻便可移植、可扩展、可读性、具有多种内建数据类型、开源等等。
使用Python的缺点有:运行速度慢,代码不能加密(解释性语言,发布python应用只能发布源代码,不像C发布编译后的应用文件)

3> 列表、元组、集合、字典的区别是什么?

  • 列表:元素可变(任何数据类型),有序(可索引),append/insert/pop;
  • 元组:元素不可变,但元素中的可变元素是可变的;有序(可索引);而且元组可以被散列,例如作为字典的键。
  • 集合:无序(不可被索引)、互异
  • 字典:无序,键值对(key:value),key唯一不可重复

4> xrange和range的区别是什么?

xrange返回一个xrange生成器对象,而range返回一个list对象。
生成很大数列的时候,range会使用和其范围大小相同的内存;相比xrange的性能要高很多。

5> Python中的模块和包是什么?

在Python中,模块就是一种构建程序的方式。每一个Python程序文件都是一个模块,这个文件还可以引入其他模块如对象和属性等。 包就是一个带有__init__.py文件的文件夹,里面可包含多个模块

6> **这两个参数是什么意思:*args,kwargs?我们为什么要使用它们?

python中规定参数前带 * 的,称为可变位置参数,只是我们通常称这个可变位置参数为*args而已,叫其他的一样一样滴。
*args:是一个列表,传入的参数会被放进列表里。
同理,python中规定参数前 带 ** 的,称为可变关键字参数,通常用**kwargs表示。
**kwargs:是一个字典,传入的参数以键值对的形式存放到字典里。

args表示任何多个无名参数,它是一个tuple;**kwargs表示关键字参数,它是一个dict。并且同时使用args和kwargs时,必须*args参数列要在kwargs前,像foo(a=1, b=‘2’, c=3, a’, 1, None, )这样调用的话,会提示语法错误“SyntaxError: non-keyword arg after keyword arg”。

如果我们不确定要往函数中传入多少个参数,或者我们想往函数中以列表和元组的形式传参数时,那就使要用*args;如果我们不知道要往函数中传入多少个关键词参数,或者想传入字典的值作为关键词参数时,那就要使用**kwargs。args和kwargs这两个标识符是约定俗成的用法.

7> Python里面search()和match()的区别

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;#re.search匹配整个字符串,直到找到一个匹配。

8> 在Python中, list, tuple, dict, set有什么区别, 主要应用在什么样的场景?

定义list: 链表, 有序的项目, 通过索引进行查找, 使用方括号"[]";
tuple: 元组, 元组将多样的对象集合到一起, 不能修改, 通过索引进行查找, 使用括号"()";
dict: 字典, 字典是一组键(key)和值(value)的组合, 通过键(key)进行查找, 没有顺序, 使用大括号"{}";
set: 集合,无序, 元素只出现一次, 自动去重, 使用"set([])";

应用场景:
list, 简单的数据集合, 可以使用索引;
tuple, 把一些数据当做一个整体去使用, 不能修改;
dict, 使用键值和值进行关联的数据;
set, 数据只出现一次, 只关心数据是否出现, 不关心其位置;

代码:

mylist = [1, 2, 3, 4, ‘Oh’]
mytuple = (1, 2, ‘Hello’, (4, 5))
mydict = {‘Wang’ : 1, ‘Hu’ : 2, ‘Liu’ : 4}
myset = set([‘Wang’, ‘Hu’, ‘Liu’, 4, ‘Wang’])

9> __new__和__init__的区别

这个__new__确实很少见到,先做了解吧.
new__是一个静态方法,而__init__是一个实例方法.
new__方法会返回一个创建的实例,而__init__什么都不返回.
只有在__new__返回一个cls的实例时后面的__init__才能被调用.
当创建一个新实例时调用__new
,初始化一个实例时用__init
.

metaclass__是创建类时起作用.所以我们可以分别使用__metaclass,__new__和__init__来分别在类创建,实例创建和实例初始化的时候做一些小手脚

创建一个新实例时调用__new__,初始化一个实例时用__init__,这是它们最本质的区别。
new方法会返回所构造的对象,init则不会.
new函数必须以cls作为第一个参数,而init则以self作为其第一个参数

10> read,readline和readlines

read 读取整个文件
readline 读取下一行,使用生成器方法
readlines 读取整个文件到一个迭代器以供我们遍历

11> 简述Python的作用域以及Python搜索变量的顺序

Python作用域简单说就是一个变量的命名空间。代码中变量被赋值的位置,就决定了哪些范围的对象可以访问这个变量,这个范围就是变量的作用域。在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域。Python的变量名解析机制也称为 LEGB 法则:本地作用域(Local)→当前作用域被嵌入的本地作用域(Enclosing locals)→全局/模块作用域(Global)→内置作用域(Built-in)
新式类和旧式类的区别,如何确保使用的类是新式类
为了统一类(class)和类型(type),python在2.2版本引进来新式类。在2.1版本中,类和类型是不同的。
为了确保使用的是新式类,有以下方法:
放在类模块代码的最前面 metaclass = type
从内建类object直接或者间接地继承
在python3版本中,默认所有的类都是新式类。

高级特性

切片(slice):切片是指获取list或tuple的一部分(或一个子集),不能对dict或set进行切片操作(因为其中的元素不是按顺序存储的)。切片的语法是:list[n1:n2:n3],其中n1为切片的起始索引,如果省略则为从0开始;n2为结束索引,若省略则为最后一个;n3则表示在起始索引和结束索引的范围内每n3个取一个元素,若省略,则每个元素都取。这个切片就像字符串的substring方法一样。

可迭代对象及迭代:迭代就是使用for循环依次访问可迭代对象中的每个元素。

什么是可迭代对象呢?
如何迭代list/dict/tuple/set/字符串:
python的for循环非常特别,在for循环中可以引用多个变量,形如:for i, j, k in …,这是要求in后的可迭代对象中也要有分别对应i,j,k多个变量的内容。

列表生成式list Comprehensions:专门用来生成一个(复杂的)list的机制。语法为:[ 对for中变量进行计算的表达式 for 变量列表 in 可迭代对象 if 对for中变量筛选的表达式],如:[ k + ’ = ’ + v for k, v in dict.items() if v % 2 == 0],这个语法真是足够灵活。

# 构建列表
my_list = [x for x in range(9)]
print(my_list)   # [0, 1, 2, 3, 4, 5, 6, 7, 8]

# 构建0-8中为偶数的列表
my_list = [x for x in range(9) if(x%2==0)]
print(my_list)   # [0, 2, 4, 6, 8]
# 构建0-8为奇数的列表,并将每个数字做平方运算
def function(number):
    return number * number

my_list = [function(x) for x in range(9) if x%2!=0]
print(my_list)   # [1, 9, 25, 49]

生成器generator:生成器可以认为是表示生成一个list的算法(而不像列表生成式那样直接生成了一个列表),list中的元素在需要时(比如访问这个元素时)才会生成(不需要时不生成,减少了内存占用,可表示无限集)。

# 构造一个生成器
gen = (i for i in range(9))

# 生成器可以被遍历
for i in gen:
    print(i)

创建生成器:方法一:把列表生成式语法中的[]替换为(),即创建了一个生成器;方法二:使用函数来创建生成器,但是用来创建生成器的函数,除了其中要有yield语句外,还是与一般的函数不同。不同之处在于在这个函数中,yield还需要放在一个循环语句中,这样,这个生成器才能生成多个列表元素。

访问生成器generator中的元素:因为generator也是可迭代对象,所以可以使用for来访问generator中的元素: for n in g: print(n)

高阶函数:就是可以将其他函数作为参数的函数。python内置的几个高阶函数有(这些高阶函数和C#中在集合上定义的扩展方法非常类似,它们的参数都是一个函数和一个可迭代对象,然后将函数作用于可迭代对象中的每个元素,产生结果):
map(f, list):传入map的函数仅有一个参数,将此函数单独作用在可迭代对象的每个元素上(也就是依次用可迭代对象中的每个元素作为此函数的参数调用,需要注意的是,在函数中没有有关此元素在list中的位置信息,所以如果遇到需在函数中使用元素的位置信息的时候,不要使用高阶函数),其返回值是一个迭代器(可以转变为list而不直接返回list);

reduce(f, list):传入reduce的函数有两个参数,达到的效果是:reduce(f, [x1, x2, x3, x4]) = f( f( f( x1, x2 ), x3 ), x4 ),reduce的返回结果,是函数的计算结果,而不再是一个迭代器或list;

filter():传入filter的函数仅有一个参数,此函数依次作用于可迭代对象的每个元素时返回一个bool结果。整个filter的运算结果是一个迭代器,但排除了上面运算结果为false的元素;

sorted():函数作为返回值和闭包:大概了解是怎么回事,但是还是有些说不清楚,也很难应用起来。

匿名函数(在python中就是lambda表达式):语法是:lambda 逗号分隔的参数列表:表达式。匿名函数的返回值就是lambda表达式的值。python中,这里的“表达式”只是一个简单的表达式,不支持复杂的语句块;

装饰器:类似于OOP中的装饰器模式,Python直接从语言层面上支持此模式。python中的装饰器可以为一个函数临时增加一些功能。Python是通过下面的步骤实现此模式的:

定义一个参数为函数、返回值也是函数的函数,即装饰器函数,在返回的函数中调用传入的参数函数及添加其他功能,也就是返回的函数成为了参数函数的一个包装器;

在定义需要临时增加一些功能的函数时,在函数前使用“@装饰器函数名”语法修饰该函数,则在调用此函数时,会转为调用在装饰器函数中定义的包装函数,从而达到临时增加功能的目的;

实际上包装器函数和原函数的一些属性还是不同的,如__name__属性等,但python通过functools模块中的wraps函数可以将原函数的属性复制给包装器函数,所以在装饰器函数中要求这么一句@functools.wrap(原函数名);

总结起来,装饰器函数有这么几个特征(1)其参数为一个函数;(2)返回值也是一个函数;(3)在返回值函数中调用参数函数并添加其他功能,达到为参数函数临时增加功能的目的;(4)通过“@装饰器函数名”的方式修饰其他函数,从而为该函数增加装饰器中增加的临时功能;(5)装饰器函数中要有这样一个语句:@functools.wrap(原函数名),用于将原函数属性复制给包装器函数;这也太笨拙了吧?

模块是Python中组织源代码的一种机制,一个.py文件就是一个模块,模块名是该.py文件所在的文件夹名与文件的组合,用.分隔,即“文件夹名.文件名”;

用文件夹来组织模块的方式,称为“包(Package)”。可以作为包的文件夹中必须包含一个__init__.py文件(这个__init__.py文件本身可以为空,也可以包含代码,它本身也是一个模块,但它的模块名不是__init__,而是它所在文件夹的名称),否则该文件夹只是一个普通的文件夹而非“包”(“包”类似C#中命名空间的机制)。

内置模块只要安装了Python,内置模块就可以使用。使用模块的第一步是导入模块,语法为import 模块名,如:
import sys
导入模块后,将相当于定义了一个与模块同名的变量sys,使用该变量来引用该模块,如sys.argv,就是引用模块sys中定义的变量argv。

面向对象编程的内容:类、对象、类和对象的成员、封装、继承、多态;类及其成员的可访问性public/private/protected;构造函数

定义类的语法:class 类名( 基类 ):,object是所有类的基类,如果上面的定义中省略了基类,则默认从object继承,如:class Student( object ):;

构造函数及创建对象:如果定义类时,未显式定义类的构造函数,则类默认拥有一个无参数的构造函数,如果显示定义了构造函数,则此默认构造函数就不再存在。类的构造函数名必须是__init__。创建对象时,传入的参数必须与类的构造函数的参数匹配(self参数除外);

类和对象的属性:

类属性:(1);(2)可以为类动态添加属性,如:Student.score = 90,这样的属性相当于C#的静态成员,为类动态添加的属性会立即体现在类的对象中;(3)以__开头的属性是private,不能直接访问(这不是约定,而是python的限制),如果需要访问,则需要定义对应的get/set方法;(4)类似__xxx__的属性都是类的特殊变量,但不是private的;

对象属性:可以为对象动态添加属性,如student1.score = 80;如果对象的属性与类的属性重名,则对象的属性覆盖类的属性;这个可能和javascript的属性访问机制一样,即从底层开始,找到后即不在继续向上层查找;

类的方法:(1)与普通函数的区别在于,类的方法,其第一个参数永远是self(语法是:def methodname(self)),但在调用时不必传入该参数;(2)也可以为类动态添加方法,先定义一个第一个参数是self的方法,动态添加方法的语法是:类名.方法名 = MethodType( 方法名, 类名 )

继承和多态:继承和多态总体上来讲和C#一样,区别在于:python中在子类中定义的与父类同名的方法,自动全部是多态的(以__开头的方法除外,C#有覆盖和复写的区别,python没有?),python中有无类似abstract机制?python中有没有protected/protected internal的机制?

获取对象信息,使用以下函数:
type():用来判断对象的类型。python的设计不严谨,这个type()函数就是个很好的例子。type()函数返回值的类型是什么呢?是类。那是什么类呢?他可以和int/str/bool/bytes(对于基本数据类型)、类名(对于一般类)、types模块中定义的常量(如:FunctionType等)比较。是不是太灵活了?

isinstance():判断某个变量是否为某种或某几种类型,返回值为True或者False;

dir():获取一个对象所有的属性和方法,返回值是一个包含对象所有属性和方法名的list;

hasattr()/getattr()/setattr():用于判断一个属性/方法名(字符串表示)是否为一个对象的属性/方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值