zoukankan      html  css  js  c++  java
  • Python基础总结与实践

    Python简介

    • Python是一种动态解释型编程语言,在模块载入时将源码编译成字节码, 这些字节码被虚拟机PVM解释执行,其中解释执行是Python性能较低的主要原因;
    • Python使用C语言编写,可以和C,C++,Java等语言结合使用:Java在Python上的实现Jython,具体参考:https://docs.python.org/2/tutorial/index.html,和.NET互通的IronPython,https://ironpython.codeplex.com/

    编译执行

    编译通常发生在模块载入的时候,编译器先将源码编译成字节码,保存在pyc文件中,如果使用-O参数,可生成pyo文件,是一种简单优化后的pyc文件;

    对于pyc文件,编译过程如下:

    • 核对文件Magic标记,Magic为一个特殊数字,由Python版本号计算得出,作为pyc文件检查的标记;
    • 检查时间戳和源码文件修改时间是否相同,以确定是否需要重新编译;
    • 载入模块;

    对于py文件,编译过程如下:

    • 对源码进行AST(抽象语法树)分析;
    • 将分析结果编译成PyCodeObject;
    • 将 Magic、源码⽂件修改时间、PyCodeObject 保存到 pyc 文件中;
    • 载入模块; 

    执行可使用eval和exec函数,eval()用来执行一个表达式,exec用来执行一个代码片段,execfile()可动态执行一个py文件;

    Pyhton基础与实践

    主要介绍Python语言中一些基础但又很重要的知识,python对象、函数、类、正则表达式、编码转换等。

    对象

    一切皆对象

    Python中一切皆为对象,每个对象都包含一个标准头,头信息由 "引用计数" 和 "类型指针" 组成。

    "引用计数"为PVM中主要的垃圾回收机制,每当对象被引用时增加,超出作用域或调用del手工释放后递减,计数为0时被回收;

    通过"类型指针"可明确知道对象的类型,指向Type对象,包含了其继承关系以及静态成员信息;

    可使用sys.getrefcount(x)来查看对象的引用计数;

    type(x)x.__class__可查看对象类型;

    hex(id(x))返回对象内存地址;

    对于变长对象,其头部会多出一个记录元素数量的字段;

    x=10
    sys.getrefcount(x)  #查看x引用计数,形参会增加一次计数;
     
    import types
    types(x)  #查看x的类型信息;
    x.__class__  #__class__通过类型指针来获取对象类型;
    

    对象类型

    不可变类型:None,bool,int,float,long,complex,string,unicode,tuple,frozenset;
    可变类型:list,dict,set

    #bool
    int(True) # 1
    int(False) # 0
     
    #float
    '''float默认采用双精度,可能不能精确表示十进制小数'''
    float('0.1')*5 == float('0.5') # False
    round('2.675',2) # 2.67
    #Decimal可精确控制位数,一般用Decimal代替float
    from decimal import Decimal
    Decimal('0.1')*5 == Decimal('0.5') # True
     
    #str,unicode
    '''需要注意编码问题,使用decode(),encode()方法,一个项目中使用不同类型的编码,很容易造成错误'''
    import logging
    logger = logging.getLogger('test')
    logger.info('%s is not %s' % (u'测试汉字', '测试汉字')) #Error,混用两种不同类型编码
    #python2.x默认编码为ascii,一般情况下需要进行转码操作,大部分情况下,我们在Python脚本头部都会将默认编码设为utf-8
    # -*- coding: utf-8 -*-
    import sys
    sys.getdefaultencoding() # ascii
    #字符串拼接,一般情况下:join > '%s%s' > +,字符串前面加'r',表示不转义;
     
    #dict
    #对于大字典,建议用迭代器代替keys(),values(),items()方法,降低内存开销
    d={'a':'xxx'.....}
    d.iterkeys(),d.itervalues(),d.iteritems()
    #求两个dict差集
    d1 = {'a':1, 'b':2}
    d2 = {'b':2, 'c':3}
    v1 = d1.viewitems()
    v2 = d2.viewitems()
    v1 & v2, v1 | v2, v1 - v2, vi ^ v2 # 相当于set
    #dict是哈希表,默认是无序的,如需有序字典,可使用OrderedDict
    from collections import OrderedDict
    od = OrderedDict()
    od['a'] = 'qqq'
    od['b'] = 'bbb'
    for k,v in od.items(): print k,v # 按添加顺序输出
     
    #set
    #判重公式: (a is b) or (hash(a) == hash(b) and eq(a,b))
    #要将自定义类型放入set,需要重写__hash__和__eq__方法
    class User(Object):
        def __init__(self, name):
            self.name = name
     
        def __hash__(self):
            return hash(self.name)
     
        def __eq__(self, other):
            if not other or not isinstance(other, User):
                return false
            return self.name == other.name
    

      表达式

    正则表达式

    正则表达式基本在任何语言中都出现,对于开发来说,是必备的技能之一,Python正则表达式详见https://docs.python.org/2/library/re.html

    #IP地址匹配
    import re
    def check_ip(ip):
        pattren = r'^(25[0-5]|2[0-4]d|1d{2}|[1-9]d|[0-9]).XXX$' #不全,剩下类似
        if re.match(pattern, ip):
            return True
        return False
    
    #由zimbra邮箱同步数据到AD的脚本中正则表达式应用实例:
    def get_mail_attrs(self, mail_info):
        pattern = r'^cn:|^displayName|^mail:|^zimbraACE:.*ownDistList$|^(?!zimbra).*@'
        attrs = {}
        attrs['managedBy'] = []
        split_info = mail_info.split('
    ')
        for line in split_info:
            if re.match(pattern, line):
                item = line.strip().split(': ')
                if item[0] == 'zimbraACE':
                    _id = item[1].split()[0]
                    if _id in self.id_mail:
                        _mail = self.id_mail[_id]
                        attrs['managedBy'].append(_mail)
                    else:
                        print 'Error, %s has no mail' % _id
                elif len(item) > 1:
                    attrs[item[0]] = item[1]
                else:
                    if 'members' not in attrs:
                        attrs['members'] = []
                    attrs['members'].append(item[0])
    #在字符串中使用正则表达式,如果不使用'r'标记,需要使用双重转义;
    

      语句

    注意循环和异常中的else,如:while...else...,for...else...,try...except...else...finally...,else在循环正常退出时执行,在except没有捕捉到异常时执行;
    列表推导式

    #举例说明列表推导式的应用
    def test(x):
        return x**2
    a = [test(x) for x in xrange(10) if x%2]
    b = [text(x) for x in open('number.txt', 'r')]
    #生成字典
    c = {c:ord(c) for c in 'abc'}
    d = {d:chr(d) for d in '123'} #enumerate使用 for idx,num in enumerate([x for x in range(10)]): print "index[{0}] = {1}".format(idx, num)

      函数

    函数在同一名字空间中是不能重载的(由 __dict__[name] 唯一性决定),且总是有返回值,默认返回None;

    引用传递

    Python中都是按引用传递的,不管是赋值还是函数传参,不管是可变类型还是不可变类型;
    按引用传递与按值传递的区别:引用传递传递的是内存地址,而值传递传递的是当前值的一个副本;

    a = 10
    b = 10
    hex(id(a)) == hex(id(b))    #True
    a is b    #True
    #函数参数传递,需要注意顺序,默认参数必须在位置参数之后,*args和**kwargs必须在默认参数之后;
    def test(a, b, c=10, d='ww', *args, **kwargs):
        print args,kwargs
    #如默认参数是使用def创建函数时生成的对象,以后调用函数会复用此对象,如第一次调用test后,a为[1],第二次调用后,a为[1,1];
    def test(a=[]):
        a.append(1)
        print hex(id(a))
        print a

    #对于可变对象,可使用deepcopy来进行深度复制,copy.deepcopy(x);

      名字空间

    python名字空间可理解为系统和自定义对象的name/object字典;

    Python变量是一个字符串对象,它和目标对象一起在名字空间中构成一个 name/object 关联项,名字空间决定了对象的作用域和生存周期;

    变量没有类型,对象有,变量的作用仅仅是在某个时刻与名字空间中的目标对象进行关联;

    globals()获取模块级别名字空间,locals()获取当前上下文名字空间;

    可以通过<module>.__dict__访问其他模块的名字空间;

    对象查询顺序遵循LEGB原则,即locals -> enclosing -> globals -> __builtins__

    常用函数

    Python有许多常用函数可直接调用,如lambda,map,zip等,具体使用不再详细介绍。

    Python 2.X版本中类模型有两种,Classic Class和New-Style Class,Classic Class支持多继承,但已被Python 3.0抛弃,大家在使用类时建议多使用New-Style Class,即继承object的类。

    类中访问成员时,成员查找顺序: instance.__dict__ -> class.__dict__ -> baseclass.__dict__;

    Python的内置类方法:getattr(obj, name[, default]),setattr(obj, name, value),hasattr(obj, name),delattr(obj, name);

    Python的内置类属性:__dict__,__name__,__doc__,__module__,__bases__等;

    属性

    Python内置函数property()可以实现属性;

    class Test(object):
         
        def get_name(self):
            return self.__name
        def set_name(self, value):
            self.__name = value
        def del_name(self):
            del self.__name
     
        name = property(get_name, set_name, del_name)
     
    class Test2(object):
         
        user_id = property(lambda self: self._user_id)
        user_name = property(lambda self: self._user_id, lambda self,value: setattr(self, '_user_name', value))
    

      垃圾回收

    Python的垃圾回收主要以引用计数为主,标记清除和分代回收为辅,理解垃圾回收的过程有助于编写代码不易造成内存泄露;
    优先级:引用计数 > 标记清除 和分代回收

    JSON与time模块

    #JSON与Python对象之间的转换
    json.dumps(x) #encoding的过程,将Python对象x编码转换为JSON字符串
    json.loads(x) #decoding的过程,将JSON字符串x解码转换为Python对象
      
    #time模块
    #Python有两种表示时间的方式,时间戳以及数组形式。
    #常用函数
    time.clock() #第一次执行获取当前程序的执行时间,之后获取从第一次到当前程序运行所花费时间;
    time.sleep() #单位为秒
    time.ctime() #将时间戳转换为时间字符串
    time.localtime([seconds]) #将时间戳转换为当前时区的数组形式
    time.mktime(tuple) #将数组形式time对象转换为时间戳
    time.strftime(format[, tuple]) #将数组形式time对象转换为指定格式化形式
    time.strptime(string, format) #将时间字符串根据指定格式转换为数组形式time对象
    time.time() #获取当前时间的时间戳
      
    #获取当前文件所在绝对路径
    os.path.dirname(os.path.abspath(__file__))
    

      

  • 相关阅读:
    华为交换机S5700设置远程ssh telnet登录
    华为交换机S5700 vty 0 4
    OpenStack--Cinder(G版)中的volume type
    nova volume-create的使用
    druid监控配置
    2PC之JTA原理与实现
    线上服务内存OOM问题定位
    分布式系统事务一致性解决方案
    Spring MVC异常统一处理的三种方式
    Git回滚到历史节点(SourceTree篇)
  • 原文地址:https://www.cnblogs.com/pflee/p/4278849.html
Copyright © 2011-2022 走看看