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|1\d{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('\n')
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__))

  

Python基础总结与实践的更多相关文章

  1. 零python基础--爬虫实践总结

    网络爬虫,是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本. 爬虫主要应对的问题:1.http请求 2.解析html源码 3.应对反爬机制. 觉得爬虫挺有意思的,恰好看到知乎有人分享的一个爬虫 ...

  2. Python+Selenium基础入门及实践

    Python+Selenium基础入门及实践 32018.08.29 11:21:52字数 3220阅读 23422 一.Selenium+Python环境搭建及配置 1.1 selenium 介绍 ...

  3. python基础实践 -python是一门动态解释性的强类型定义语言

    python是一门动态解释性的强类型定义语言 Python能做什么? Python是一门综合性的语言,你几乎能在计算机上通过Python做任何事情,以下是Python应该最广泛的几个方面: 1.网络应 ...

  4. 人工智能实践:linux 和 python 基础简介

    linux下的目录 绝对路径:是以根目录(" / ")为起点的完整路径,以你所要到的目录为终点. 相对路径:是你当前的目录(" .")为起点的路径,以你所要到的 ...

  5. Python 基础 四 面向对象杂谈

    Python 基础  四  面向对象杂谈 一.isinstance(obj,cls) 与issubcalss(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls ...

  6. Python基础-类

    Python基础-类 @(Python)[python, python基础] 写在前面 如非特别说明,下文均基于Python3 摘要 本文重点讲述如何创建和使用Python类,绑定方法与非绑定方法的区 ...

  7. Python基础-类变量和实例变量

    Python基础-类变量和实例变量 写在前面 如非特别说明,下文均基于Python3 大纲: 1. 类变量和实例变量 在Python Tutorial中对于类变量和实例变量是这样描述的: Genera ...

  8. Python基础总结

      刚学习Python时,边学边总结的,采用思维导图的形式, 适合回顾使用.内容参考<Python:从入门到实践>一书.   再给出一张Datacamp网站上的一张关于Python基础的总 ...

  9. 10个Python基础练习项目,你可能不会想到练手教程还这么有趣

    美国20世纪最重要的实用主义哲学家约翰·杜威提出一个学习方法,叫做:Learning By Doing,在实践中精进.胡适.陶行知.张伯苓.蒋梦麟等都曾是他的学生,杜威的哲学也影响了蔡元培.晏阳初等人 ...

随机推荐

  1. 【leetcode 5. 最长回文子串】解题报告

    方法一:中心扩展算法 解题思路:从左到右每一个字符都作为中心轴,然后逐渐往两边扩展,只要发现有不相等的字符,则确定了以该字符为轴的最长回文串,但需要考虑长度为奇数和偶数的不同情况的处理(长度为偶数时轴 ...

  2. JAVA中的工厂方法模式和抽象工厂模式

    工厂方法模式: 定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类.类型:创建类模式类图: 类图知识点:1.类图分为三部分,依次是类名.属性.方法2.以& ...

  3. 初识Composer

    关于vendor name和project name的区别? 包名(package name)包含了供应商名(vendor name)和项目名(project name)是为了避免命名冲突的 requ ...

  4. 2017-10-3 清北刷题冲刺班a.m

    P99zhx a [问题描述]你是能看到第一题的 friends 呢.——hja怎么快速记单词呢?也许把单词分类再记单词是个不错的选择.何大爷给出了一种分单词的方法,何大爷认为两个单词是同一类的当这两 ...

  5. 洛谷P2911 [USACO08OCT]牛骨头Bovine Bones【水题】

    题目大意:输入S1,S2,S3,随机生成三个数x,y,z,求x+y+z出现次数最多的数(如果有多个答案输出最小的),其中1<=x<=S1,1<=y<=S2,1<=z< ...

  6. Sqlyog问题

    Sqlyog没有架构设计器的解决方法 更换注册码即可

  7. C 语言实例 - 计算标准偏差

    C 语言实例 - 计算标准偏差 计算标准偏差. 实例 #include <stdio.h> #include <math.h> float calculateSD(float ...

  8. jmeter 签名MD5生成(转)

    请求接口需要同时发送签名,签名定义为: 可以看出签名就是把用户的密码 .用户名 和签名key生成一个md5串就可以了 刚好jmeter 有个md5 生成,生成前需要获取name ,password k ...

  9. sourcetree基本使用

    非常有用的使用sourcetree开发的步骤文档 https://www.cnblogs.com/fps2tao/p/7825742.html 1) master,最终发布版本,整个项目中有且只有一个 ...

  10. 练习四十六:列表排序,删除list中重复的元素

    方法一:使用集合set;将list直接转换为set a = [1,3,4,3,5,7] a = list(set(a)) print(a) 执行结果: [1, 3, 4, 5, 7] 方法二:直接排序 ...