【Python】 零碎知识积累 I

时间:2022-09-03 22:50:04

  大概也是出于初高中时学化学,积累各种反应和物质的习惯,还有大学学各种外语时一看见不认识的词就马上记下来的习惯,形成了一种能记一点是一点的零碎知识记录的癖好。这篇文章就是专门拿来记录这些零碎知识的,没事的时候看看回忆回忆,说不定也能学到点什么。

  ■  关于输出不同进制数

  在格式化输出字符串中可以写%d,%x,%o来分别输出十、十六、八进制的值

  但是并没有二进制的转换输出,想要二进制时可以用bin函数,bin(num)会输出'0bxxxx',xxxx就是num的二进制表达了

  ■  其实习惯了写for A in ... 的形式,但很多时候可以把A替换为A,B这种元组形式,这样可以让表达更加清晰。比如

for item in dict.items():
#换成
for key,value in dict.items():

  

  ■  要善于看文档。碰到不认识的函数,模块等可以看其__doc__,或者help(...),以及。。度娘

  ■  import keyword;print keyword.kwlist 可以查看python中所有的关键字,感觉没有想象的那么多..+

  

  ■  id函数可以用来查看某个对象在内存中的地址值,借助id可以来看两个对象是不是引用了同一个内存地址还是只是值上的相等。

  

  ■  给函数传递参数时,如果混合了虚名实名参数,那么虚名参数一定要写在实名参数之前,否则python无法识别参数顺序,并报错:

func(value1,value2,param3=value3)    #正确

func(param3=value3,value1,value2)    #错误

  ■  类中的方法可以创建本类的实例。当然不包括构造方法,否则就无限递归了。。

  ■  关于赋值和复制

  赋值就是用 = 号的语句,而复制在Python中又可以分为浅复制和深复制。

  赋值语句只是单纯的多关联一个引用。常见的说明这一点的例子就是我让a和b两个变量都等于某个列表,通过a引用列表修改其内容后,通过b访问到的就是修改过后的内容了。换句话说,赋值没有复制任何引用关系,是复制了零层引用关系。

  浅复制的操作有比如copy模块的copy方法,序列的切片,list/dict等可变对象的类型方法等。通过这些操作得到的内容赋值给某个变量之后,这个变量相对于原值就是一个通过浅复制得到的东西。浅复制的特点是只复制最表面的一层引用关系。比如有a=[1,2,3,[4]],令b = copy.copy(a)。之后查看id(a)和id(b),可以看到两者是不同的。但是id(a[3])和id(b[3])却是相同的。原因就是浅复制只复制第一层关系。

  深复制相对的,就是复制所有相关的引用关系了。上面例子中的id(a[3])和id(b[3])也会变得不同了。

  ■  eval 和 repr 和 exec

  这三个函数看起来都很黑科技

  1.  eval是evaluate的简称,可以将符合格式的str转化成list,tuple,dict等数据格式。除了转换格式之外,eval也可以解析字符串,调用python函数,并且返回此语句的返回值。,比如eval('open("file","r").read()')可以返回某文件的内容(但是不能有语句 比如eval('import os')或者eval('print 1')都是会报错的)

  2.  repr是represent的简称,将各种数据类型转化成str,是eval的一种逆操作。但是repr和str()不同。

    简单来说,repr是把传递进来的参数原原本本的转化成一个字符串,甚至包括引号,举例子如下:

>>>print repr('a\nb')
'a\nb' #注意是带引号的
>>>print r'a\nb'
a\nb #不带引号但是因为是r开头的字符串,不对\n做转义解释
>>>print 'a\nb'
a
b

    而str则是致力于生成一个给人看的字符串,虽然在内存中他有可能还是带有未转义字符的,但是print出来之后是人可以一眼看明白的

    简而言之,print repr(...)所得到的东西就是...,连引号都算在里面。当然,这个用repr转化字符串并没有啥实际意义,因为转化出来的东西肯定有引号。总之要清楚这两者不一样就好了

  3.  exec用来将字符串转化为语句。

    虽然看起来和eval好像很像,但区别在于eval是返回值的,而exec不返回值,只做操作

    如:

>>> eval('1+2')
3
>>> exec('1+2') #返回值是None,但是内存中进行了1+2的计算
>>> eval('print \'1+2\' ')
SyntaxError: invalid syntax
>>> exec('print \'1+2\' ')
1+2

    另外,eval和exec除了第一个参数是一个字符串之外,还可以加上一个第二个参数,是个字典。这个字典的意义就是为前面字符串里的特定变量赋值,相当于一个小命名空间:

>>>exec('print a+1',{'a':2})
3

    再另外,eval和exec是有一定安全风险的,比如一个web应用接受用户的一些数据来做操作,可能你期盼用户发送一个规则的字符串过来然后懒一点直接用eval把它给python化,但是如果他传过来一个'open("file","w").close()',如果直接eval掉,那就相当于把之前存在的file给清了。。这样这个用户就达到了攻击目的。

  ■  上节中说到了str和repr的区别,那就顺便提一下__str__和__repr__的区别。这两个魔法方法的共同点是要返回一个字符串,但是这个字符串被用在不同的地方,举例如下:

class Test(object):
def __init__(self):
pass def __repr__(self):
return "Expression of repr" def __str__(self):
return "Expression of str" ######在python shell中######
>>>sample = Test()
>>>sample
Expression of repr
>>>print sample
Expression of str

  也就是说,通常我之前所说的对象在内存中的值,其实是指这个类在定义__repr__时返回的字符串,这个字符串也是函数repr(sample)的返回值。而print语句,则是提取出__str__方法的返回值并且把它输出到stdout上。
  以str类型为例,str的__str__方法返回的就是这个字符串本身的值,而__repr__方法会在两端自动加上两个单引号。在python shell中键入变量名直接回车是显示内存中的值的嘛,但是我要用什么方法来表示它是个字符串呢,自然就是要往显示出来的值里面加上两个引号了。但是呢字符串的值本身是没有引号的,所以repr方法为其加上引号,就是为了人在键入变量名查看内存中的值时可以看懂其是个字符串。

  

  ■  在遍历字典时,用for key,value in dict.items()更加直观。

  ■  lambda语句和lambda函数(匿名函数)

    和def一个函数相对来看,lambda语句的作用是建立一个匿名函数,并返回这个函数对象。函数处理过程较为简单的函数可以用lambda来简化代码。另外,可以把返回出来的函数对象实名化:

add = lambda a,b : a+b
#冒号右边紧跟的就是返回值,不能是None。也可以是个返回值不为None的函数嘛
#冒号左边写这个匿名函数的参数,可以写零到若干个。

    lambda的实际应用有很多,我暂时可以想到的就有序列在进行sorted时用的key参数可以是个匿名函数对象来实现根据某个指标排序。另外wxpython中的事件绑定,Bind方法,若用匿名函数可以实现向事件处理函数传递参数的功能。

  ■  不要忘了max(seq)和min(seq)两个显而易见的函数。挺有用的

  ■  经常用到的if语句的条件判断,其实不止能判断True和False,对于其他类型的数据,如[],(),{},"",None都是会被判成False的。而里面有数据的话就又是True.所以以后写条件可以不用写if ls == []:怎么样怎么样,而直接if ls:就好了,简洁明了!

■  global关键字用于把跟着的变量声明为全局变量。在看似不属于其的命名空间里也可以引用它。

■  讲一个一维列表二维化的方式,用简单的一行语句来表达:

[[array[rows*y+cols] for cols in range(y)] for rows in range(x)]
#array是一个一维列表(或者数组),x表示二维化后的行数,y表示列数

■  想用C,java里面的switch语句结构,但是python里没有的时候,可以

  1.  搞很多个if判断,不过这样很繁琐

  2.  建立一个字典,key是switch的各个case的值,而value写函数对象进行相应的操作

■  关于在函数的参数前加*,分成两个情况

  1.在定义函数的时候:需要知道的是,很多场合下写的*args,**kwargs中的args和kwargs只是一种习惯,你可以把它换成其他变量名称,在函数中换那个名称引用就可以了。
    一个*表示函数可以接受任意多个函数,它会把所有不是实名参数的参数整合成一个元组,并把其作为参数名代表的对象。比如:

def test(paraA,paraB,*args):
print paraA
print paraB
print type(args),args if __name__ == "__main__":
test(1,2,3,4,5) #输出:
1
2
<type 'tuple'> (3,4,5)

    两个**表示可以接受任意多个实名参数,即传参数的时候超过限额的部分也可以加上参数的名称了。而函数会把kwargs整合成一个字典供函数引用。比如:

def test(paramA,paramB='B',**kwargs):
print paramA
print paramB
print type(kwargs),kwargs if __name__ == "__main__":
test(1,2,C=3,D=4,F=5) #输出
1
2
<type 'dict'> {'C':3,'D':4,'F':5} test(1,2,3,4,5) #报错,参数个数不对

   2. 调用函数时加上*

    当在调用函数时参数前加上*,(这个参数通常是个sequence之类的iterable对象)意思是把参数值拆分成一个个小单元,并将小单元一一传递给函数作为参数。单元的个数和函数定义时要求的参数值一致。比如:

    

def test(a,b,c):
print "a:",a
print "b:",b
print "c:",c if __name__ == "__main__":
test(*[1,2,3]) #输出:
a: 1
b: 2
c: 3

■  说到函数的实名虚名参数问题,还有一个顺序问题需要注意。就是说在定义和使用时虚名参数一定要放在实名参数之前

  def func(a,b,c=1)  正确

  def func(a,b=1,c)  错误

■  zip函数

  zip函数接受包括0个在内任意多个sequence作为参数。将每个sequence的[0]组合成元组1,[1]组合成元组2........

  最终返回的是[元组1,元组2,元组3....]

  如果参数的长度参差不齐,那就以短的序列为标准,即长的序列多于最短的那个长度的那部分全部都舍去

■  if和else可以写在一行里

  比较容易想到的是[x for x in range(10) if x%2 == 0]这样的列表生成器

  这种列表表达式还可以接上else:[x if x%2 == 0 else x*3 for x in range(10)] 相当于偶数原封不动输出,奇数乘以三

  上面这种表达式的根源是类似后面这个表达式的用法 a if a>0 else -a (计算绝对值)

  在函数的返回语句中大概可以通过这样的表达式来做一个最后的判断。return a if a > 0 else -a

■  类里面可以出现一些常量,写在所有成员方法的外面,前面不用写self.,但是调用的时候要用self.常量名调用。

  比如:

class test():
class_dict = {"ip":"127.0.0.1"}
def __init__(self):
self.port = 8080 def __str__(self):
return self.class_dict.get("ip"),self.port print test()
>>>127.0.0.1 8080

  但是一般来说和java里面不一样,这些常量起的都是一些辅助作用

■  Python中自带了round函数来进行小数的进位工作。比如round(1.234,2)就可以得到1.23。而round(1.235,2)可以得到1.24。

■  利用好__future__的unicode_literals

  众所周知,Python3版本中的字符串都是默认是unicode类型而不是str类型了,这大大方便了文本处理之类的工作。那么在Python2里面如何使用这个特性,就在代码开始的地方from __future__ imort unicode_literals即可。

  需要注意的是,即使是默认所有字符串变量都是unicode了也不意味着可以省去文件头上面的coding=xxx的声明。IDE都是无法直接识别中文等非ascii字符的。为了不报syntax error就需要coding=xxx这声明

【Python】 零碎知识积累 I的更多相关文章

  1. 【Python】 零碎知识积累 II

    [Python] 零碎知识积累 II ■ 函数的参数默认值在函数定义时确定并保存在内存中,调用函数时不会在内存中新开辟一块空间然后用参数默认值重新赋值,而是单纯地引用这个参数原来的地址.这就带来了一个 ...

  2. Python OOP知识积累

    目录 目录 前言 对象 类 面向对象 Python 面向对象编程三个基本特征 封装 继承 继承的作用 泛化与特化 实现继承的方式 多重继承 多态 方法多态 最后 前言 Python是一个功能非常强大的 ...

  3. &lbrack;转&rsqb;Python零碎知识&lpar;2&rpar;&colon;强大的zip

    一.代码引导 首先看这一段代码: 1 >>> name=('jack','beginman','sony','pcky') 2 >>> age=(2001,2003 ...

  4. python小知识积累

  5. Python基础知识思维导图&vert;自学Python指南

    微信公众号[软件测试大本营]回复"python",获取50本python精华电子书. 测试/开发知识干货,互联网职场,程序员成长崛起,终身学习. 现在最火的编程语言是什么?答案就是 ...

  6. 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸

    类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...

  7. Python开发【第二篇】:Python基础知识

    Python基础知识 一.初识基本数据类型 类型: int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**31-2**31-1,即-2147483648-2147483647 在64位 ...

  8. python基础知识(二)

    以下内容,作为python基础知识的补充,主要涉及基础数据类型的创建及特性,以及新数据类型Bytes类型的引入介绍

  9. WinRT知识积累1之读xml数据

    前述:这个知识是在Windows8.1或WP8.1中运用Linq to xml获取一个xml文件里的数据.(网上也很多类似的知识,可以借鉴参考) 平台:windows8.1 metro 或者WP8.1 ...

随机推荐

  1. 《Linux及安全》实践3&period;3

    <Linux及安全>实践三 字符集总结与分析 [by lwr] 一.ISO.UCS/UTF.GB系列字符集分析 1.字符集&字符编码 字符集(Charset):是一个系统支持的所有 ...

  2. maven中snapshot快照库和release发布库的区别和作用

    在使用maven过程中,我们在开发阶段经常性的会有很多公共库处于不稳定状态,随时需要修改并发布,可能一天就要发布一次,遇到bug时,甚至一天要发布N次.我们知道,maven的依赖管理是基于版本管理的, ...

  3. 利用checkinstall制作deb或rpm工具包

    1. 概述 有时候我们向用户提供软件时,并不希望提供源码(虽然这挺狗的...),而是只希望提供一些可执行文件.小程序还好说,可以轻易地提取有用的信息出来. 但对于一些比较庞大的程序,尤其是需要配置文件 ...

  4. Ubuntu配置OpenGL环境

    建立基本编译环境 sudo apt-get install build-essential 安装OpenGL Library sudo apt-get install libgl1-mesa-dev ...

  5. cassandra 如何写数据以及放置副本

    application发送数据到server application 发送请求到server 根据设置的load balance 规则从cluster中挑选一个coordinator,一般使用轮询即可 ...

  6. c&num; http请求ajax页面

    我们在用Http请求的时候,某些页面是ajax加载的,所以请求过来的页面数据不完整.也就是说ajax局部加载数据的地方,我们请求不到,这时候该怎么办呢? WebDriver+phantomjs 这两个 ...

  7. NOIP2013提高组 T2 火柴排队

    一开始看也想不到这居然要用到逆序对,归并排序. 先来看看题目: 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间 ...

  8. MySQL 实战笔记

    01 | 基础架构:一条SQL查询语句是如何执行的? 大体可以分为: Server 层:包含了连接器.查询缓存.分析器.优化器.执行器,跨存储引擎的功能都在这一层实现的,比如存储过程.触发器.视图等. ...

  9. x-pack

    x-pack安装>官网安装步骤https://www.elastic.co/downloads/x-pack >x-pack简介X-Pack是一个Elastic Stack的扩展,将安全, ...

  10. 【BZOJ3745】Norma(CDQ分治)

    [BZOJ3745]Norma(CDQ分治) 题面 BZOJ 洛谷 题解 这种问题直接做不好做,显然需要一定的优化.考虑\(CDQ\)分治. 现在唯一需要考虑的就是跨越当前中间节点的所有区间如何计算答 ...