python基本知识梳理
怎么样学习python?
在接触python的过程中,总感觉知识零散,学完就忘。当时python零起步的时候,跟着菜鸟教程学习基本语法和应用,后面需要用python做数据分析项目,于是更加深入地进行学习,接触numpy,pandas,matplotlib,seaborn,pymysql等模块。
个人觉得好的学习python的路径是:
1、首先总体学习python的基本语法,了解python的基本操作。
2、其次根据书本例子一步一步训练相关技巧。
3、根据项目的需要,借助百度,python官方文档来理解和掌握模块和函数的具体用法。
4、借助其他资料日积月累地优化python的代码设计和操作技巧。
知识点整理
本文整理一些比较常用的基本知识点:
1、python处处皆对象。
2、空白符皆有意义,编码的时候注意控制缩进。
3、解释器逐条解释,写一条,解释一条语句。比如:a = b = 1; c = a + b; 此时,c的值就已经被设置为2。(很多编程范式下,c只有在被用到时,才会被求值。)
4、变量赋值,实际上是在为等号右边的内容创建引用。改变等号右边的值,两边的值都会改变。
In [5]: a = [1,2,3]
In [6]: b = a
In [7]: a.append(4)
In [8]: a
Out[8]: [1, 2, 3, 4]
In [9]: b
Out[9]: [1, 2, 3, 4]
5、将对象作为参数传递给函数的时候,永远看做是引用传递,不会发生任何复制。
6、python强烈要求对象有明确的类型,尽管引用没有与之相关联的数据类型。比如:a = 5 我们并不需要制定a 为 int ,但是,‘2’+2 会报错,而不是得到‘22’ ,你可以用‘2’ + str(2) 来转换得到。 可以用isinstance(2,int)来判断对象是不是属于某个类。
7、python的字符串是不可变的。两个字符串加起来,就是一个新的字符串。
In [1]: a = "string can't be changed"
In [2]: a[10] = 'a'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-210f5679316f> in <module>()
----> 1 a[10] = 'a'
TypeError: 'str' object does not support item assignment
新的字符串需要重新创建。如:
In [3]: b = 'a new string'
In [4]: b = a.replace('string','string in python')
#repalce是整体替换,当被替换的对象有多个的情况下,需要用到re.sub
#re.sub 利用正则表达式实现字符串的替换处理
#可以参考:http://www.cnblogs.com/nkwy2012/p/6548812.html
8、字符串中若出现太多的‘\’ 或其他特殊符号,或者你从别处导入的数据容易产生该类情况,则可以在字符串***最左边加上r***,表示所有字符按原样进行解释。
9、字典、集合、列表均有推导式。利用update方法可实现字典的融合。del、pop可以删除字典中的值。get,pop 方法可以根据key返回值,若key不存在,get返回None,pop会抛出异常。
In [12]: d1 = {'o':'orange','b':'banana'}
In [14]: d1.update({'a':'apple'})
In [15]: d1
Out[15]: {'o': 'orange', 'b': 'banana', 'a': 'apple'}
In [19]: d1['a']
Out[19]: 'apple'
In [20]: d1.get('d')
In [21]: d1.pop('d')
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-21-6bbc3ed7635a> in <module>()
----> 1 d1.pop('d')
KeyError: 'd'
10、python的datetime模块提供datetime、date、time等类型。利用pandas从一个包含日期和时间的datetime 对象 obj 中单独取出日期和时间
pd.datetime(obj).dt.date pd.datetime(obj).dt.time
In [27]: dt = datetime(2018,10,06,12,12,12)
File "<ipython-input-27-8134fa9e7965>", line 1
dt = datetime(2018,10,06,12,12,12)
^
SyntaxError: invalid token
#2018年5月6日,5和6前面不要加0,否则编译器会报错
In [28]: dt = datetime(2018,5,6,12,12,12)
In [29]: dt = datetime(2018,5,6)
In [30]: dt
Out[30]: datetime.datetime(2018, 5, 6, 0, 0)
In [31]: dt.minute
Out[31]: 0
#strftime 方法将datetime按需求格式化为字符串
#可以只转部分日期,或者时间
In [33]: dt.strftime("%m/%d/%y %H%M")
Out[33]: '05/06/18 0000'
In [34]: dt.strftime("%m/%d/%y")
Out[34]: '05/06/18'
#replace可实现替换
In [37]: dt.replace(minute = 12,second = 5)
Out[37]: datetime.datetime(2018, 5, 6, 0, 12, 5)
#不要数前加0
In [38]: dt.replace(minute = 12,second = 05)
File "<ipython-input-38-69ef8fc04d01>", line 1
dt.replace(minute = 12,second = 05)
^
SyntaxError: invalid token
#两个datetime的差是一个datetime.timedelta类型,
#datetime与timedelta的和将形成新的datetime
11、元组一旦创建完毕,中间的值便不可再修改。对一个元组乘以一个整数,相当于连接了该元组的多个副本。
In [43]: tup = ('orange','apple')
In [44]: len(tup)
Out[44]: 2
In [45]: tup[1]='banana'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-45-5003314bfa87> in <module>()
----> 1 tup[1]='banana'
TypeError: 'tuple' object does not support item assignment
#元组拆包
In [47]: a,b= tup
In [48]: a
Out[48]: 'orange'
In [49]: tup2 = tup*4
In [50]: tup2
Out[50]: ('orange', 'apple', 'orange', 'apple', 'orange', 'apple', 'orange', 'apple')
#元组的count方法
In [51]: tup2.count('orange')
Out[51]: 4
13、zip用于将多个序列(元组或者列表)中的元组进行“配对”。zip(*obj)可以对拥有配对的对象进行解除配对。
In [67]: seq1 = ['a','b','o']
In [68]: seq2 = ['apple','banana','orange']
In [69]: z = zip(seq1,seq2)
#python2中返回的是list of tuples
#python3中返回的是 iterator of tuples
#详见官方文档
In [70]: z
Out[70]: <zip at 0x3dddc08>
#python 3 输出:
In [71]: list(z)
Out[71]: [('a', 'apple'), ('b', 'banana'), ('o', 'orange')]
In [85]: list(z)
Out[85]: []
In [89]: z = zip(seq1,seq2)
In [90]: a,b = zip(*z)
In [91]: a
Out[91]: ('a', 'b', 'o')
In [92]: b
Out[92]: ('apple', 'banana', 'orange')
14、将元祖构成的列表“扁平化”成为一个简单的整数列表:
In [93]: res = [(1,2,3),(4,5,6),(7,8,9)]
In [94]: li = [x for tups in res for x in tups ]
In [95]: li
Out[95]: [1, 2, 3, 4, 5, 6, 7, 8, 9]
15、python诸如生成器,lambda函数、闭包等也很重要。
16、python 中 的 is、==
:
- is 判断两个变量是否引用的是同一个对象,
哪些对象才是同一个对象?
看下面这个例子:
a = 10
b = 10
print (a is b)#true
a = 10
def f():
return 10
print (f() is a)#true
a = 1000
def f():
return 1000
print (f() is a)#false
以上代码的输出原因:
###小整数的缓存###
Python中把-127到128这些小整数
都缓存了一份。这和Java的Integer类是一样的。所以,对于-127到128之间的整数,整个Python虚拟机中就只有一个实例。不管你什么时候,什么场景下去使用 is 进行判断,都会是True。
a = 10.0
b = 10.0
print (a is b)#true
a = 10.0
def f():
return 10.0
print (f() is a)#false
若编译编译这部分内容之后可以发现:
整个python文件其实就是一个大的对象,f 所对应的那个函数也是一个
对象,这个code对象做为整体是大的
对象的consts域里的一个const项。
在大对象里,有10.0这样的一个const项,f 这个
对象所对应的conts里呢,也有一个10.0这个浮点数。
首先加载前一个10.0,生成PyFloatObject1
,a,b 变量使用这个PyFloatObject1
,而f中的10.0需等到函数调用的时候才初始化,故两者不是同一个对象了。
参考:https://www.jb51.net/article/131559.htm
总之,is 需要谨慎使用。
python中,“==” 用来判断两个对象的值是否相等
(跟 Java 不同,Java 中 == 用来判断是否是同一个对象)。
**
python中format函数
**
In[2]: "[DEBUG]: enter {}()".format("fuck")
Out[2]: '[DEBUG]: enter fuck()'
print('{名字}今天{动作}'.format(名字='陈某某',动作='拍视频'))
陈某某今天拍视频
"[DEBUG]: enter {}".format("fuck")
Out[4]: '[DEBUG]: enter fuck'
grade = {'name' : '陈某某', 'fenshu': '59'}
print('{name}电工考了{fenshu}'.format(**grade))
陈某某电工考了59
print('{1}今天{0}'.format('拍视频','陈某某'))#通过位置
print('{0}今天{1}'.format('陈某某','拍视频'))
陈某某今天拍视频
陈某某今天拍视频
#填充和对齐 ^ < > 分别表示居中、左对齐、右对齐,后面带宽度
print('{:^14}'.format('陈某某'))
print('{:>14}'.format('陈某某'))
print('{:<14}'.format('陈某某'))
print('{:*<14}'.format('陈某某'))
print('{:&>14}'.format('陈某某'))
陈某某
陈某某
陈某某
陈某某***********
&&&&&&&&&&&陈某某
#精度和类型f精度常和f一起使用
print('{:.1f}'.format(4.234324525254))
print('{:.4f}'.format(4.1))
4.2
4.1000
# 进制转化,b o d x 分别表示二、八、十、十六进制
print('{:b}'.format(250))
print('{:o}'.format(250))
print('{:d}'.format(250))
print('{:x}'.format(250))
11111010
372
250
fa
# 千分位分隔符,这种情况只针对与数字
print('{:,}'.format(100000000))
print('{:,}'.format(235445.234235))
100,000,000
235,445.234235
def debug():
import inspect
caller_name = inspect.stack()[1][3]
print ("[DEBUG]: enter {}()".format(caller_name))
def say_hello():
debug()
print ("hello!")
def say_goodbye():
debug()
print ("goodbye!")
if __name__ == '__main__':
say_hello()
say_goodbye()
[DEBUG]: enter say_hello()
hello!
[DEBUG]: enter say_goodbye()
goodbye!
函数有千千万,你只管你自己的函数,别人的函数参数是什么样子,鬼知道?还好Python提供了可变参数*args和关键字参数**kwargs
,有了这两个参数,装饰器就可以用于任意目标函数了。
#debug 修饰函数say
def debug(func):
def wrapper(*args, **kwargs): # 指定宇宙无敌参数
print "[DEBUG]: enter {}()".format(func.__name__)
print 'Prepare and say...'
return func(*args, **kwargs)
return wrapper # 返回
@debug
def say(something):
print "hello {}!".format(something)
至此,你已完全掌握初级的**
装饰器
**写法。
闭包
闭包定义:
1、闭包是一个嵌套函数
2、闭包必须返回嵌套函数
3、嵌套函数必须引用一个外部的非全局的局部自由变量
https://blog.csdn.net/yitiaodashu/article/details/79025502
嵌套函数可以使用被嵌套函数中间的变量,就像普通函数可以使用全局变量一样,不需要进行参数的引入.
i = 1
def f():
i = 2
def g():
print(i)
return g
func = f()
func()#2
print(i)#1
**
命名空间:
**
函数的全局命名空间始终是定义该函数的模块,而不是调用该函数的代码所在的命名空间.