深入理解Python [1] 基础复习(上篇)

468 阅读6分钟

前言

大学的时候就自己学过Python,当时刚起步用的是国内翻译的教材《Python基础教材》,一本黄黑色的教材;一开始读得很认真,但是书中例子极少,再加上一些糟糕的翻译,对于一个初学者来说,着实晦涩难懂,不知所云。后来在微博上听到@ibuick和@tinyfool同时说到,学编程一开始就强迫自己学英文的,这样以后习惯了,对自己好处很大,于是在国外找了一个Python的视频教程看了起来,居然还学完了,自信心也因此上来了,在化学深渊的我好像看到了一束光

深入理解Python系列专题基于视频课程《Deep Dive in Python》所做的笔记,是在读者有一定Python基础上展开的,如果之前学过一点儿Python但是忘记很多了,没关系,本篇将会带大家温习下Python的基础,热身完之后,我们便要开始Deep Dive in python 了

Python中有很多术语翻译成中文会很奇怪,不太方便大家的理解,故直接采用英文

Python类型体系

数字(Numbers)

我们平常用的最多的数字无非是浮点数,整数之类的,但是在Python中关于数字到底是有哪些类型呢? 在Python中其实一共有六种数字类型,分为IntergralNon-Integral,具体参考以下表格

数字(Numbers)
Integral Non-Integral
整数(Integers) 浮点数(Floats)
布尔值(Booleans) 复数(Complex)
小数(Decimals)
分数(Fractions)

以上的数据类型会在后面每个都单独展开细讲,这里不过多赘述了

集合(Collections)

和常用的数字一样,我们平时使用的集合最多的就是列表(list)和字典(dictionary),它们具体是怎样分类的呢

集合(Collections)
序列(Sequences) 数组(Sets) 映射(Mappings)
可变的(Mutable) 不可变的(Immutable) 可变的(Mutable) 不可变的(Immutable) 可变的(Mutable)
列表(Lists) 元组(Tuples) 数组(Sets) 冰冻数组(Frozen Sets) 字典(Dictionaries)
字符串(Strings)

以上的内容我们也会在后面单独讲解

可被调用对象(Callables)和单例(Singletons)

Callables Singletons
用户定义的函数(User-defined Functions) None
生成器(Generators) NotImplemented
类(Classes) Ellipsis
实例方法(Instance Methods)
类实例(通过定义__call__())
内建函数(例如len(), open())
内建方法(例如my_list.append())

多行语句和字符串

物理行和逻辑行

什么事物理行和逻辑行?举个例子

 spam = [1, 
         2,
         3] 
            
#以上这个语句有三个物理行,但是编译过程中会被直接转成一个逻辑行

一个逻辑行的结束是由一个NEWLINE Token所决定的,为了使多个物理行变成一个逻辑行,一般情况下,逻辑行结尾的newline Character一般在编译过程中被忽略的;

像上述例子中,定义一个list直接用一行不就行了吗,为什么需要物理行这个概念呢?其实,物理行存在的意义就是为了提供代码的可读性

转换的显性与隐性

#隐性的例子可以使用在
list literals: []
tuple literals: ()
dictionary literals:{}
set literals:{}
function arguments / parameters

以上这些也同时支持行内注释(inline comments)

e.g.
[1,#item1
 2,#item2
 3,#item3
 ]
 
def my_func(a,
            b,#comment
            c):
    print(a,b,c)
    
my_func(10,#comment
        20,30)


#显性转换,通过利用"\" 字符,可以将语句变成多行,语句中不支持行内注释

if a
   and b
   and c: #错误示范,这个语句不会被自动转换成逻辑行
   
if a \
   and b \
   and c: #正确
   
if a \
   and b \ #comment
   and c: #错误示范,语句中不支持行内注释

多行字符串

通过使用三个引号,可以创建多行字符串

'''This is 
a multi-line string'''

像换行符,tabs这些看不到的字符,也是包括在字符串里面的

变量名称

  1. 变量必须以下划线(_)或者某个字符开头,然后可以尾随下划线,字符,还有数字
  2. 变量不能命名为保留字(reserved words)
常用保留字

None True False 
and or not
if else elif
for while break continue pass
def lambda global nonlocal return yield
del in is assert class 
try except finally raise
import from with as
  1. Python中命名的一些惯用约定:

1⃣ ️_my_var,开头以下划线的命名,一般是希望此对象为内部使用,例如以这种方式命名的对象就不会被以下语句导入(注意⚠️,这里并不是说这个对象就是私有的(private),这只是一种命名习惯而已,想导入这种类型的对象还是做得到的)

from module import *  #导入失败

from moudle import _my_var #导入成功

2⃣️__my_var__,开头结尾以双下划线的命名,一般是系统定义的名称,我们先看下PEP-8文件是怎么说的

__double_leading_and_trailing_underscore__: "magic" objects or attributes that live in user-controlled namespaces. E.g. __init__, __import__ or __file__. Never invent such names; only use them as documented.

Python都叫你不要乱发明这种变量了,自己就别作死了

#当我们比较两个数字大小时,python其实是做了一个转换
a, b = 10, 20

a < b      

a.__lt__(b) #上面的语句转成此语句

#所以永远不要自己发明这种变量,因为你不知道未来python会有哪些新的内建对象

3⃣️__my_var,仅开头用双下划线命名的变量

这个变量命名最特别,它一般会触发所谓的name mangling

举个栗子 我有一个教练朋友,叫CoachLong

class CoachLong:
    
    def __init__(self):
    	self.location = 'Le Shan'
    	self.hobby = 'Stay in Gym'
    	self.__girlfriend = 'Diaochan'

    def profile(self):
        print('I live in %s, my hobby is %s, and my wife is %s' % (self.location, self.hobby, self.__girlfriend))
        

然后我又是这个教练的会员,在他的影响下,我的兴趣爱好和他一样了,所以我可以继承他了,但是地址和女朋友是不一样的,我的女友当然是广末凉子啦

class MemberTang(CoachLong):
	def __init__(self):
		super(MemberTang,self).__init__()
		self.location = 'Shang hai'
		self.__girlfriend = 'Hirosue Ryoko'

然后让我们分别来看看我们档案什么样子

long = CoachLong()
tang = MemberTang()
long.profile()
tang.profile()

第一行会打印出

I live in Le Shan, my hobby is Stay in Gym, and my wife is DiaoChan

没有问题! 然后看看我的档案什么样子

I live in Shang hai, my hobby is Stay in Gym, and my wife is DiaoChan

地址变了,很好,但是教练的女友也变成来我的女友!!我的女友是广末凉子啊,朋友妻不可欺啊🐶

当然,教练的女友不是随随便便就可以取得的

long.location() => Le Shan
long.__girlfriend() => "AttributeError: 'CoachLong' object has no attribute '__girlfriend'"

不过通过特殊手段,还是可以获取教练的女友的

long._CoachLong__girlfriend => 'DiaoChan' 总而言之,通常这种命名方式,就是希望不会那么轻松地获取那个属性

4⃣️其它的一些约定

类型 规定 例子
Packages 短,全部小写,一般不用下划线 utilities
Modules 短,全部小写,可以用下划线 db_utils
Classes 驼峰写法(CamelCase) BankAccount
Functions 小写,下划线分离单词 open_account
Variables 同上 account_id
Constants 全部大写,下划线分离 MIN_APR

条件语句

基础的条件语句就不说了,if...elif...else...应该都烂熟于心了

条件表达式(Conditional Expression)

简化的条件表达式有一个固定的模式: X if (condition is true) else Y

#通过条件表达式,将下述语句简化
a = 25
if a < 5:
    b = 'a < 5'
else:
    b = 'a >= 5'
    
# 上面可以等价于
b = 'a < 5' if a < 5 else 'a >= 5'

这个语句真的好方便