精华内容
下载资源
问答
  • def foo(*args, **kwargs): print 'args = ', args print 'kwargs = ', kwargs if __name__ == '__main__': foo(1,2,3,4) # args = (1, 2, 3, 4) kwargs = {} foo(a=1,b=2,c=3) # args = () kwargs = {...
  • python面试题问答题

    千次阅读 2018-12-07 13:34:56
    python面试题问答题 1.对比 *args **kwargs 的区别 __new__ __init__ 的区别 is == 的区别 range xrange 的区别 答案: (1)*args 表示非关键字收集参数,收集的实参会组成一个元组,接收没有任何形参接收的非...

    python面试题问答题

    1.对比

    *args     **kwargs   的区别
    __new__   __init__   的区别
      is      ==         的区别
    range 	  xrange   的区别
    

    答案:

    (1)*args 表示非关键字收集参数,收集的实参会组成一个元组,接收没有任何形参接收的非关键字实参。可以与普通形参共存。

    **kwargs 表示关键字收集参数,收集的实参会组成一个字典,形参名作为键,值为值,仅接收没有任何形参接收的关键字参数。可以与普通形参共存。

    并且同时使用*args和**kwargs时,必须*args参数列要在**kwargs前。

    (2)_init_: 当实例对象创建完成后被调用的,初始化对象时触发,参数至少一个self,接收对象。使用该方式初始化的成员都是直接写入对象当中,类中无法具有。

    _new_:是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例,是个静态方法。参数至少一个cls,接收当前类。必须返回一个对象是实例,触发顺序:先触发__new__才会触发_init_。也就是,__new__在__init__之前被调用,__new__的返回值(实例)将传递给__init__方法的第一个参数,然后__init__给这个实例设置一些参数。

    (3)is和==都是对对象进行比较判断作用的,但对对象比较判断的内容并不相同。

    is: 同一性运算符 这个运算符比较判断的是对象间的唯一身份标识,也就是id是否相同。

    ==:是python标准操作符中的比较操作符,表示判断两个值的数据类型,数据值,是否一致。

    (4)range :range会直接生成一个list对象

    xrange:并不会直接生成一个list对象,会在每一个调用时返回其中的一个值。

    在 python3 中,去除了 range 函数,将 xrange 函数更名为 range 函数

    2.常用的版本控制工具及其常用命令

    答案:

    版本控制工具:git
        
    常用命令:
        * git add .
        * git status 
        * git commit 提交至本地仓库
        * git origin
        * git push
    

    3.装饰器用途:@staticmethod 和@classmethod,@property用途

    答案:

    @classmethod:类方法,类方法是给类用的,类在使用时会将类本身当做参数传给类方法的第一个参数,python为我们内置了函数classmethod来把类中的函数定义成类方法。

    @staticmethod:静态方法

    @property:属性方法:将一个类方法转变成一个类属性,只读属性。便于访问

    4.怎么样的二级容器不能强转成字典

    答案:

    不等长的二级容器不能转化成字典

    5.写尽可能多的str对象的方法?

    1、全部大写:str.upper()

    str1 = 'nostalgia'
    str2 = str1.upper()
    print(str2)
    
    NOSTALGIA
    

    2、全部小写:str.lower()

    str1 = 'NOSTALGIA'
    str2 = str1.lower()
    print(str2)
    
    nostalgia
    

    3、大小写互换:str.swapcase

    str1 = 'No Smouking'
    str2 = str1.swapcase()
    print(str2)
    
    nO sMOUKING
    

    4、首字母大写,其余小写:str.capitalize()

    str1 = 'nostalgia fly'
    str2 = str1.capitalize()
    print(str2)
    
    Nostalgia fly
    

    5、首字母大写:str.title()

    str1 = 'nostalgia fly'
    str2 = str1.title()
    print(str2)
    
    Nostalgia Fly
    

    6、应对所有字母的小写:str.casefold()

    #str.lower() 只能转换ASCII字母。
    str1 = 'NOSTALGIA'
    str2 = str1.casefold()
    print(str2) 
    
    nostalgia
    

    6.什么是lamada函数?下面这段代码输出的是什么?

    nums = range(2,20)
    for i in nums:
        nums = filter(lambda x:x==i or x % i,nums)
    nums
    
    <filter at 0x493c898>
    
    print(list(nums))
    
    [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
    

    lambda表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。lambda表达式是一种简洁格式的函数。该表达式不是正常的函数结构,而是属于表达式的类型。

    定义lambda函数的形式如下(lambda参数:表达式)lambda函数默认返回表达式的值。你也可以将其赋值给一个变量。
    lambda函数可以接受任意个参数,包括可选参数,但是表达式只有一个。

    7.python里面如何拷贝一个对象?(赋值、浅拷贝、深拷贝的区别)

    答案:

    赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。

    浅拷贝:创建一个新的对象,但它包含的是对原始对象中包含项的引用(如果用引用的方式修改其中一个对象,另外一个也会修改改变){1,完全切片方法;2,工厂函数,如list();3,copy模块的copy()函数}

    深拷贝:创建一个新的对象,并且递归的复制它所包含的对象(修改其中一个,另外一个不会改变){copy模块的deep.deepcopy()函数}

    8.介绍一下except的用法和作用?

    Python的except用来捕获所有异常, 因为Python里面的每次错误都会抛出 一个异常,所以每个程序的错误都被当作一个运行时错误。

    一、下面是使用except的一个例子:

    try:

    foo = opne(̶file”) #open被错写为opne
    except:

    sys.exit(̶could not open file!”)

    因为这个错误是由于open被拼写成opne而造成的,然后被except捕获,所以debug程序的时候很容易不知道出了什么问题

    二、下面这个例子更好点:

    try:

    foo = opne(̶file”) # 这时候except只捕获IOError

    except IOError:

    sys.exit(̶could not open file”)

    9.python中pass语句的作用是什么?

    pass语句什么也不做,一般作为占位符或者创建占位程序,pass语句不会执行任何操作,比如:

    while False:

    pass
    

    pass通常用来创建一个最简单的类:

    class MyEmptyClass:

    pass
    

    10.如何用python来进行查询和替换一个文本字符串?

    可以使用sub()方法来进行查询和替换,sub方法的格式为:sub(replacement, string[, count=0])

    • replacement是被替换成的文本
    • string是需要被替换的文本
    • count是一个可选参数,指最大被替换的数量
    import re 
    p = re.compile('blue|white|red')
    print(p.sub('color','blue socks and red shose'))
    print(p.sub('color','blue socks and red shose',count=1))
    
    color socks and color shose
    color socks and red shose
    

    11.python里面如何生成随机数

    在 Python 中用于生成随机数的模块是 random,在使用前需要 import. 如下例子可以酌情列举:

    • random.random():生成一个 0-1 之间的随机浮点数;
    • random.uniform(a, b):生成[a,b]之间的浮点数;
    • random.randint(a, b):生成[a,b]之间的整数;
    • random.randrange(a, b, step):在指定的集合[a,b)中,以 step 为基数随机取一个数;
    • random.choice(sequence):从特定序列中随机取一个元素,这里的序列可以是字符串,列表,元组等。
    import random
    print(random.random())
    print(random.uniform(1,10))
    print(random.randint(1,10))
    print(random.randrange(1,10,2))
    print(random.choice([1,2,5,7,8,0]))
    
    0.6590161194936338
    2.4275244943455623
    7
    9
    2
    

    12.有没有一个工具可以帮助查找python的bug和进行静态的代码分析

    PyChecker是Python代码的静态分析工具,它能够帮助查找Python代码的bug,而且能够对代码的复杂度和格式等提出警告。

    PyChecker可以工作在多种方式之下。首先,PyChecker会导入所检查文件中包含的模块,检查导入是否正确,同时检查文件中的函数、类和方法等。

    PyChecker可以检查出来的问题有如下几种:

    • 全局量没有找到,比如没有导入模块
    • 传递给函数、方法、构造器的参数数目错误
    • 传递给内建函数和方法的参数数目错误
    • 字符串格式化信息不匹配
    • 使用不存在的类方法和属性
    • 覆盖函数时改变了签名
    • 在同一作用域中重定义了函数、类、方法
    • 使用未初始化的变量
    • 方法的第一个参数不是self
    • 未使用的全局量和本地量(模块或变量)
    • 未使用的函数/方法的参数(不包括self)
    • 模块、类、函数和方法中没有docstring

    Pylint是另外一个工具可以进行codingstandard检查

    13.python中的关键字yield有什么作用?

    1. 保存当前运行状态(断点),然后暂停执行,即将函数挂起
    2. 将yeild关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用,当使用next()、send()函数让函数从断点处继续执行,即唤醒函数。

    14.print(dir(‘a’))的输出?

    dir():

    调用这个方法将返回包含obj大多数属性名的列表(会有一些特殊的属性不包含在内),obj的默认值是当前的模块对象。

    print(dir('a'))
    
    ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
    

    hasattr(obj, attr):
    这个方法用于检查obj是否有一个名为attr的值的属性,返回一个布尔值。判断一个对象里面是否有name属性或者name方法,返回BOOL值,有name特性返回True, 否则返回False。
    需要注意的是name要用括号括起来

    class test():
        name="xiaohua"
        def run(self):
            return "HelloWord"
    t = test()
    print(dir(t))
    
    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'run']
    
    hasattr(t,'name')
    
    True
    
    hasattr(t,'run')
    
    True
    

    getattr(obj, attr):

    获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。
    需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,
    可以在后面添加一对括号。

    getattr(t,'name') #获取name属性,存在就打印出来。
    
    'xiaohua'
    
    getattr(t,'run')#获取run方法,存在就打印出方法的内存地址
    
    <bound method test.run of <__main__.test object at 0x0000000004DA68D0>>
    
    getattr(t,'run')()#获取run方法,后面加括号可以将这个方法的返回值打印
    
    'HelloWord'
    

    setattr(obj, attr, val):
    给对象的属性赋值,若属性不存在,先创建再赋值。

    setattr(t,'name','haohao')
    hasattr(t,'name')
    getattr(t,'name')
    
    'haohao'
    

    15.说说dict的items()方法与iteritems()方法的不同

    答案:

    字典的items方法作用:是可以将字典中的所有项,以列表方式返回。因为字典是无序的,所以用items方法返回字典的所有项,也是没有顺序的。

    字典的iteritems方法作用:与items方法相比作用大致相同,只是它的返回值不是列表,而是一个迭代器。

    16.python中的变量作用域(变量查找顺序)。

    答案:

    函数作用域的LEGB顺序

    1. 什么是LEGB?

    L:local 函数内部作用域

    E:enclosing 函数内部与内嵌函数之间

    G:global 全局作用域

    B:build-in 内置作用域

    1. 它们是作什么用的?为什么非要介绍这个呢?或者说它们的作用是什么?
      原因是因为我们的在学习Python函数的时候,经常会遇到很多定义域的问题,全局变量,内部变量,内部嵌入的函数,等等,Python是如何查找的呢?以及Python又是按照什么顺序来查找的呢?这里做一个顺序的说明

    2. 顺序是什么
      跟名字一样,Python在函数里面的查找分为4种,称之为LEGB,也正是按照这种顺序来查找的。

    首先,是local,先查找函数内部

    然后,是enclosing,再查找函数内部与嵌入函数之间(是指在函数内部再次定义一个函数)

    其次,是global,查找全局

    最后,是build-in,内置作用域

    17.描述python的进程、线程及协程的功能,以及它们的不同地方和适用场景

    进程是操作系统资源分配的最小单位

    线程是CPU调度的单位

    进程切换需要的资源最大,效率很低

    线程切换需要的资源一般,效率一般(当然在不考虑GIL的情况下)

    协程切换任务资源很小,效率高

    多进程、多线程根据cpu核数不一样可能是并行的,但是协程是在一个线程中 所以是并发

    18.说明os,sys模块的不同,并列举常用的模块方法:

    os: This module provides a portable way of using operating system dependent functionality.
    翻译:提供一种方便的使用操作系统函数的方法。

    sys:This module provides access to some variables used or maintained by the interpreter and to functions that interact strongly with the interpreter.
    翻译:提供访问由解释器使用或维护的变量和在与解释器交互使用到的函数。

    总结就是,os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。

    常用模块方法:os.path os.mkdir

    19.python里面的search()和match()的区别:

    match()函数只检测RE是不是在string的开始位置匹配, search()会扫描整个string查找匹配, 也就是说match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none
    例如:

    import re
    print(re.match('super','superstition'))
    print(re.match('super', 'insuperable'))
    
    <_sre.SRE_Match object; span=(0, 5), match='super'>
    None
    

    search()会扫描整个字符串并返回第一个成功的匹配
    例如:

    import re
    print(re.search('super','superstition').span())#返回(0, 5)
    print(re.search('super','insuperable').span())#返回(2, 7)
    
    
    (0, 5)
    (2, 7)
    

    20.python匹配HTML tag的时候,<.>和<.?>有什么区别?

    答案:

    正则匹配的贪婪和非贪婪模式

    • 贪婪模式在整个表达式匹配成功的前提下,尽可能多的匹配
    • 非贪婪模式在整个表达式匹配成功的前提下,尽可能少的匹配。

    20.python是如何进行内存管理的?

    Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。

    Python中所有小于 256个字节的对象都使用 pymalloc实现的分配器,而大的对象则使用系统的 malloc。

    另外Python对象,如整数,浮点数和 List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。
    在Python中,许多时候申请的内存都是小块的内存,这些小块内存在申请后,很快又会被释放,由于这些内存的申请并不是为了创建对象,所以并没有对象一级的内存池机制。这就意味着 Python在运行期间会大量地执行 malloc和free的操作,频繁地在用户态和核心态之间进行切换,这将严重影响Python的执行效率。为了加速 Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。这也就是之前提到的 Pymalloc机制。

    import sys sys.getrefcount()查看引用计数

    字符串中间有空格!?等会重新创建新的字符串

    总结

    1. 小整数[-5,257)共用对象,常驻内存,不会被释放。
    2. 单个字符共用对象,常驻内存。
    3. 单个单词,不可修改,默认开启intern机制,共用对象,引用计数为 0,则销毁 。
    4. 大整数不共用内存,引用计数为0,销毁 .
    5. 数值类型和字符串类型在 Python 中都是不可变的,这意味着你无法修 改这个对象的值,每次对变量的修改,实际上是创建一个新的对象 .

    gc模块

    Python的GC模块主要运用了引用计数来跟踪和回收垃圾。在引用计数的基础上,还可以通过“标记-清除”解决容器对象可能产生的循环引用的问题。通过分代回收以空间换取时间进一步提高垃圾回收的效率。

    一、垃圾回收机制

    导致引用计数+1的情况

    1. 对象被创建,例如a = “hello”
    2. 对象被引用,例如b=a
    3. 对象被作为参数,传入到一个函数中,例如func(a)
    4. 对象作为一个元素,存储在容器中,例如list1=[a,a]

    引用计数机制的优点:

    1. 简单
    2. 实时性:一旦没有引用,内存就直接释放了。不用像其他机制等到特定时机。实时性还带来一个好处:处理回收内存的时间分摊到了平时。

    引用计数机制的缺点:

    1. 维护引用计数消耗资源
    2. 循环引用,解决不了

    标记-清除

    • 标记-清除的出现打破了循环引用,也就是它只关注那些可能会产生循环引用的对象
    • 缺点:该机制所带来的额外操作和需要回收的内存块成正比。

    隔代回收

    原理:将系统中的所有内存块根据其存活时间划分为不同的集合,每一个集合就成为一个“代”,垃圾收集的频率随着“代”的存活时间的增大而减小。也就是说,活得越长的对象,就越不可能是垃圾,就应该减少对它的垃圾收集频率。那么如何来衡量这个存活时间:通常是利用几次垃圾收集动作来衡量,如果一个对象经过的垃圾收集次数越多,可以得出:该对象存活时间就越长。

    21.分别说说函数cmp,map,reduce,filter的作用?

    答案:

    cmp:compare比较 python2中的函数,python3中没有

    cmp(a,b) a < b 返回-1; a > b 返回1; a = b返 回0

    map:映射

    map(function, iterable) # 将function作用于iterable,每个元素,返回的是一个map对象

    # 例:
    def plus_one(x):
        return x+1
    res = map(plus_one,[1,2,3,4])
    print(res)
    print(list(res))
    
    <map object at 0x0000000004FDF438>
    [2, 3, 4, 5]
    

    reduce 对于序列内所有元素进行累计操作

    reduce(function,iterable),用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。

    在 Python3 中,reduce() 函数已经被从全局名字空间里移除了,它现在被放置在 functools 模块里,如果想要使用它,则需要通过引入 functools 模块来调用 reduce() 函数:

    from functools import reduce
    def add(x,y):
        return (x + y)
    res = reduce(add,[1,2,3,4,5])
    print(res)
    
    
    15
    

    filter:过滤器

    filter(function, iterable) # 将 function依次作用于iterable的每个元素,如果返回值为true, 保留元素,否则从iterable里面删除

    # 例:
    def bigger_than_three(x):
        return (x>3)
    res = filter(bigger_than_three,[1,2,3,4,5])
    print(res)
    print(list(res))
    
    <filter object at 0x0000000004FDF5C0>
    [4, 5]
    

    22.分别简述一下列表,元组,字典,集合的特点

    答案:

    列表:有序,可修改,元素可重复

    1. 可以用list()函数或者方括号[]创建,元素之间用逗号’,‘’分隔。
    2. 列表的元素不需要具有相同的类型
    3. 使用索引来访问元素
    4. 可切片

    元组:有序,不可修改,元素可重复

    1. 可以用tuple()函数或者方括号()创建,元素之间用逗号’,‘’分隔。
    2. 元组的元素不需要具有相同的类型
    3. 使用索引来访问元素
    4. 可切片
    5. 元素的值一旦创建就不可修改!!!(这是区别与列表的一个特征)

    字典:键值对,无序,可修改,键不可重复,值可以重复

    1. 元素由键(key)和值(value)组成
    2. 可以用dict()函数或者方括号()创建,元素之间用逗号’,‘’分隔,键与值之间用冒号”:”隔开
    3. 键必须是唯一的,但值则不必。值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组
    4. 使用键(key)来访问元素

    集合:无序,不可修改,唯一性

    1. 可以用set()函数或者方括号{}创建,元素之间用逗号”,”分隔。
    2. 与字典相比少了键
    3. 不可索引,不可切片
    4. 不可以有重复元素

    23.简述你对迭代器,生成器和可迭代对象的理解;列表,字典,字符串是可迭代对象还是迭代器?

    答案:

    Python可迭代对象(Iterable)

    我们已经知道可以对list、tuple、str等类型的数据使用for…in…的循环语法从其中依次拿到数据,我们把这样的过程称为遍历,也叫迭代。

    我们把可以通过for…in…这类语句迭代读取1条数据供我们使用的对象称之为可迭代对象(Iterable)。

    两种方法:

    1. 可迭代对象.iter()
    2. iter(可迭代对象)

    如何判断对象是否可以迭代
    可以使用isinstance()判断1个对象是否是Iterable对象:

    from collections import Iterable
    print(isinstance([],Iterable))
    print(isinstance({},Iterable))
    print(isinstance('abc',Iterable))
    mylist= [1,2,5,6,6]
    print(isinstance(mylist,Iterable))
    print(isinstance(100,Iterable))
    
    
    True
    True
    True
    True
    False
    

    迭代器:

    迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束。

    使用迭代器的优点

    • 对于原生支持随机访问的数据结构(如tuple、list),迭代器和经典for循环的索引访问相比并无优势,反而丢失了索引值(可以使用内建函数enumerate()找回这个索引值)。但对于无法随机访问的数据结构(比如set)而言,迭代器是唯一的访问元素的方式。

    • 另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件,或是斐波那契数列等等。

    • 迭代器更大的功劳是提供了一个统一的访问集合的接口,只要定义了iter()方法对象,就可以使用迭代器访问。

    • 迭代器有两个基本的方法

      1. __next__方法:返回迭代器的下一个元素
      2. __iter__方法:返回迭代器对象本身

    下面用生成斐波那契数列为例子,说明为何用迭代器

    #代码1:直接在函数fab(max)中用print打印会导致函数的可复用性变差,
    #因为fab返回None。其他函数无法获得fab函数返回的数列。
    def fab(max): 
       n, a, b = 0, 0, 1 
       while n < max: 
           print(b)
           a, b = b, a + b 
           n = n + 1
    res = fab(5)
    print(res)
    
    1
    1
    2
    3
    5
    None
    
    #代码2:代码2满足了可复用性的需求,但是占用了内存空间,最好不要。
    def fab(max): 
       L = []
       n, a, b = 0, 0, 1 
       while n < max: 
           L.append(b) 
           a, b = b, a + b 
           n = n + 1
       return L
    res = fab(5)
    print(res)
    
    [1, 1, 2, 3, 5]
    
    #代码3:
    class Fab(object): 
       def __init__(self, max): 
           self.max = max 
           self.n, self.a, self.b = 0, 0, 1 
    
       def __iter__(self): 
           return self 
    
       def __next__(self): 
           if self.n < self.max: 
               r = self.b 
               self.a, self.b = self.b, self.a + self.b 
               self.n = self.n + 1 
               return r 
           raise StopIteration()
    res = Fab(5)
    print(res)
    for key in res:
        print(key)
    # Fabs 类通过 __next__() 不断返回数列的下一个数,
    #内存占用始终为常数
    #事实上,因为迭代器如此普遍,python专门为for关键字
    #做了迭代器的语法糖。在for循环中,
    #Python将自动调用工厂函数iter()获得迭代器,
    #自动调用__next__()获取元素,还完成了检查StopIteration异常的工作。
    
    <__main__.Fab object at 0x0000000004FC4240>
    1
    1
    2
    3
    5
    
    # 使用内建的工厂函数iter(iterable)可以获取迭代器对象:
    lst = range(3)
    ite = iter(lst)
    ite
    
    <range_iterator at 0x4fd70f0>
    

    生成器

    在一个一般函数中使用yield关键字,可以实现一个最简单的生成器,此时这个函数变成一个生成器函数。yield与return返回相同的值,区别在于return返回后,函数状态终止,而yield会保存当前函数的执行状态,在返回后,函数又回到之前保存的状态继续执行。

    #例子:使用生成器逆序yield出对象的元素
    def rev_str(my_str):
        length=len(my_str)
        for i in range(length-1,-1,-1):
            yield my_str[i]
    print(rev_str("hello"))        
    for char in rev_str("hello"):
        print(char) 
    
    <generator object rev_str at 0x0000000004D7FD58>
    o
    l
    l
    e
    h
    

    24.用你掌握的python知识,针对小朋友设计一些有趣的教学小案例,讲一下设计的理由,包括这个案例应用的知识点。

    九九乘法表,九九乘法表是从小学开始学习的口诀,贴近日常学习的数学知识,便于孩子理解。

    应用到了for…in…循环及格式化字符串等知识点

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

    25.一个编码为GBK的字符串S,要将其专程utf-8编码的字符串,应该如何操作?

    S.encode(‘utf-8’)

    26.什么是代码块

    答案:

    以冒号作为开始,用缩进划分相同作用域,这样的结构称之为代码块,是一个整体

    27.变量是什么?

    答案:
    可以改变的量,实际具体指的是内存中的一块存储空间

    28.全局变量与局部变量的区别,如何在function里面给一个全局变量赋值?

    全局变量与局部变量两者的本质区别就是在于作用域
    用通俗的话来理解的话,

    • 全局变量是在整个py文件中声明,全局范围内都可以访问
    • 局部变量是在某个函数中声明的,只能在该函数中调用它,如果试图在超出范围的地方调用,程序就报错了

    如果在函数内部定义与某个全局变量一样名称的局部变量,就可能会导致意外的效果,可能不是你期望的。因此不建议这样使用,这样会使得程序很不健全,如果真的想要在函数体内修改全局变量的值,就要使用global关键字:

    num1 = 1
    def fun():  
        global num1  
        num1 = 2  
        print("函数内修改后num1=",num1)  
    num1 = 1  
    print("初始num1=",num1)  
    fun()  
    print("运行完函数后num1=",num1) 
    
    初始num1= 1
    函数内修改后num1= 2
    运行完函数后num1= 2
    

    29.python2和python3的区别

    1. Python3 使用 print 必须要以小括号包裹打印内容,比如 print(‘hi’)
    2. python2 range(1,10)返回列表,python3中返回迭代器,节约内存
    3. python2中使用ascii编码,python中使用utf-8编码
    4. python2中unicode表示字符串序列,str表示字节序列,python3中str表示字符串序列,byte表示字节序列
    5. python2中为正常显示中文,引入coding声明,python3中不需要
    6. python2中是raw_input()函数,python3中是input()函数
    7. python2中有cmp函数,pthon3中没有
    8. python2中reduce()函数是全局函数,python3 中在functools模块中
    9. Python2有为非浮点数准备的int和long类型。int类型的最大值不能超过sys.maxint,而且这个最大值是平台相关的。可以通过在数字的末尾附上一个L来定义长整型,显然,它比int类型表示的数字范围更大.在Python3里,只有一种整数类型int,大多数情况下,它很像Python 2里的长整型。由于已经不存在两种类型的整数,所以就没有必要使用特殊的语法去区别他们。

    30.单引号,双引号,三引号的区别

    python字符串通常有单引号(’…’)、双引号("…")、三引号("""…""")或(’’’…’’’)包围;

    三引号包含的字符串可由多行组成,一般可表示大段的叙述性字符串。
    在使用时基本没有差别,但双引号和三引号("""…""")中可以包含单引号,三引号(’’’…’’’)可以包含双引号,而不需要转义

    31.字符串格式化:%和.format的区别

    字符串的format函数非常灵活,很强大,可以接受的参数不限个数,并且位置可以不按顺序,而且有较为强大的格式限定符(比如:填充,对齐,精度等)

    32.简单解释python的GIL锁

    GIL 是python的全局解释器锁

    • 同一进程中假如有多个线程运行,一个线程在运行python程序的时候会霸占python解释器(加了一把锁即GIL),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。
      GIL的问题其实是每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行代码

    • 多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个python解释器,所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大

    • 线程释放GIL锁的情况: 在IO操作等可能会引起阻塞的system call之前,可以暂时释放GIL,但在执行完毕后,必须重新获取GIL
      Python 3.x使用计时器(执行时间达到阈值后,当前线程释放GIL)或Python 2.x,tickets计数达到100

    • 在 处理像科学计算 这类需要持续使用cpu的任务的时候 单线程会比多线程快

    • 在 处理像IO操作等可能引起阻塞的这类任务的时候 多线程会比单线程快

    33.utf-8和unicode的区别是什么?

    • Unicode 是「字符集」
    • UTF-8 是「编码规则」

    字符集:为每一个「字符」分配一个唯一的 ID(学名为码位 / 码点 / Code Point)

    编码规则:将「码位」转换为字节序列的规则(编码/解码 可以理解为 加密/解密 的过程)

    广义的 Unicode 是一个标准,定义了一个字符集以及一系列的编码规则,即 Unicode 字符集和 UTF-8、UTF-16、UTF-32 等等编码……

    Unicode 字符集为每一个字符分配一个码位,例如「知」的码位是 30693,记作 U+77E5(30693 的十六进制为0x77E5)。

    UTF-8 顾名思义,是一套以 8 位为一个编码单位的可变长编码。会将一个码位编码为 1 到 4 个字节:

    34.1 * 2 . . . * 2013 的结果末尾有多少个0?请写出解题思路或者计算过程

    因数5的个数决定末尾0的个数

    2013÷5=402(取整)

    2013÷25=80(取整)

    2013÷125=16(取整)

    2013÷625=3(取整)

    402+80+16+3=501

    所以123*……20122013的计算结果的末尾有501个连续的0

    35.文件操作时:xreadlines和readlines的区别?

    read(size)
    读入指定大小的内容,以byte为单位,size为读入的字符数,返回str类型

    readline()
    readline()读取一行内容,放到一个字符串变量,返回str类型。

    readlines()
    readlines() 读取文件所有内容,按行为单位放到一个列表中,返回list类型。

    xreadlines()
    返回一个生成器,来循环操作文件的每一行。循环使用时和readlines基本一样,但是直接打印就不同

    36.谈谈你对面向对象的理解?

    面向对象的编程—object oriented programming,简称:OOP,是一种编程的思想。OOP把对象当成一个程序的基本单元,一个对象包含了数据和操作数据的函数。面向对象的出现极大的提高了编程的效率,使其编程的重用性增高。

    python面向对象的重要术语:

    • 多态(polymorphism):一个函数有多种表现形式,调用一个方法有多种形式,但是表现出的方法是不一样的。
    • 继承(inheritance)子项继承父项的某些功能,在程序中表现某种联系
    • 封装(encapsulation)把需要重用的函数或者功能封装,方便其他程序直接调用
    • 类:对具有相同数据或者方法的一组对象的集合
    • 对象:对象是一个类的具体事例
    • 实例化:是一个对象实例的实现
    • 标识:每个对象的事例都需要一个可以唯一标识这个事例的标记

    函数和面向对象编程的区别

    • 相同点:都是把程序进行封装、方便重复利用,提高效率。
    • 不同点:函数重点是用于整体调用,一般用于一段不可更改的程序。仅仅是解决代码重用性的问题。而面向对象除了代码重用性。还包括继承、多态等。使用上更加灵活。
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,770
精华内容 1,908
关键字:

python问答题

python 订阅