Python 学习笔记基础篇

本文全面介绍了Python编程语言的基础知识和高级特性,包括环境搭建、数据类型、控制结构、函数定义、模块管理、面向对象编程等内容。同时,深入探讨了Python的性能特点、常用工具如PyCharm和IPython的使用,以及类、继承、多态等面向对象编程概念。

参考教程:https://github.com/jackfrued/Python-100-Days

1 优缺点

Python 为我们提供了非常完善的基础代码库,覆盖了网络、文件、GUI、数据库、文本等大量内容,被形象地称作“内置电池(batteries included)”。

优点:用 Python 开发,许多功能不必从零编写,直接使用现成的即可。除了内置的库外,Python 还有大量的第三方库供我们直接使用。当然,我们自己开发的代码通过很好的封装,也可以作为第三方库给别人使用。

缺点:运行速度慢,代码不能加密等。

2 CPython

当我们从 Python 官方网站下载并安装好 Python 3.x 后,我们就直接获得了一个官方版本的解释器 CPython。这个解释器是用C语言开发的,所以叫CPython。在命令行下运行 python 就是启动 CPython 解释器。CPython 是使用最广的 Python 解释器。

3 PIP

PIP 是 Python 包管理工具,Python 2.7.9+ 或 Python 3.4+ 以上版本都自带 PIP 工具。

4 IPython

IPython 是一个 Python 的交互式 shell,比默认的 Python shell 好很多,支持变量自动补全、自动缩进、bash shell命令等,内置许多有用的功能函数。Jupyter Notebook( 此前称为 Ipython notebook ) 是集文本、代码、图像、公式展现于一体的超级 Python web 界面。

通过 PIP 安装 IPython 和 Jupyter:

pip install ipython 和 pip install jupyter

5 退出 Python 环境

quit()

6 执行 Python 语句

在控制台输入 python 进入 Python 环境(启动 CPython 解释器),可执行 Python 语句。

7 运行 .py 文件

在控制台可以直接运行 .py 文件,cd 进入目标目录,运行命令 python xxx.py,输入 \ 实现控制台续行。

8 安装 PyCharm

下载地址:Download PyCharm: The Python IDE for data science and web development by JetBrains

用软件打开 .py 文件,直接 Run 即可。

9 if 语句

Python 中没有用花括号来构造代码块而是使用了缩进的方式来设置代码的层次结构,如果 if 条件成立的情况下需要执行多条语句。构造出更多的分支,可以使用 if…elif…else… 结构。

10 定义函数

def add(a=0, b=0, c=0):
    return a + b + c

11 多个可变入参

在参数名前面的 * 表示 args 是一个可变参数,即在调用 add 函数时可以传入0个或多个参数。

def add(*args): 
    total = 0
    for val in args:
        total += val
    return total

12 用模块管理函数

import module as m
m.foo()

需要说明的是,如果导入的模块除了定义函数之外还有可以执行代码,那么 Python 解释器在导入这个模块时就会执行这些代码,事实上我们可能并不希望如此,因此如果我们在模块中编写了执行代码,最好是将这些执行代码放入如下所示的条件中,这样的话除非直接运行该模块,if 条件下的这些代码是不会执行的,因为只有直接执行的模块的名字才是“__main__”。

# module.py
if __name__ == '__main__':
    print('see if print')
# __name__ 是 Python 中一个隐含的变量它代表了模块的名字
# 只有被 Python 解释器直接执行的模块的名字才是 __main__

# test.py
import module
# 将 if __name__ == '__main__' 去掉试试,是否执行 print 代码

13 数组切片

数组:用于在单个变量中存储多个值。注意,Python 没有内置对数组的支持,但可以使用 Python 列表 代替。

切片:Python 的切片可以被用于数组,它基于每一个维度。

s[i:j] 表示获取 a[i] 到 a[j-1] ;

s[:-1] 表示去掉最后一个字符;

s[:-n] 表示去掉最后 n 个字符;

s[-2:] 表示取最后两个字符;

s[i:j:k] 这种格式呢,i 、j 与上面的一样,但 k 表示步长,默认为 1;

s[::-1] 是从最后一个元素到第一个元素复制一遍(反向)。

arr = [0, 1, 2, 3] arrNew = arr[1:3] print(arrNew) # [1, 2]

14 Yield 关键字

找到一篇一看即懂得博文:python中yield的用法详解——最简单,最清晰的解释_yield python-CSDN博客

15 元组

元组:用圆括号 () 括起来,可包含多个不同类型元素,元素不能修改,和列表一样可以保存多条数据。元组在创建时间和占用的空间上面都优于列表。

# 定义元组
t = ('骆昊', 38, True, '四川成都')
# 获取元组中的元素
print(t[0])
# 遍历元组
for member in t:
    print(member)
# 重新赋值
t[0] = '王大锤'  # TypeError
# 变量t重新引用了新的元组原来的元组将被垃圾回收
t = ('王大锤', 20, True, '云南昆明')
# 元组转换成列表
person = list(t)
# 列表转换成元组
fruits_tuple = tuple(fruits_list)

16 集合

集合:用花括号 {} 括起来,跟数学上的集合一致,不允许有重复元素,可以进行交集、并集、差集等运算。

set1 = {1, 2, 3, 3, 3, 2} # 怎么重复了??
set2 = set(range(1, 10))
set1.add(4)
set2.update([11, 12])
set2.discard(5)
if 4 in set2:
   set2.remove(4)
# 遍历集合容器
for elem in set2:
  print(elem ** 2, end=' ') # 经测试输出了每个元素的二次幂
# 将元组转换成集合
set3 = set((1, 2, 3, 3, 2, 1))
# 集合的交集、并集、差集、对称差运算
print(set1 & set2)
# print(set1.intersection(set2))
print(set1 | set2)
# print(set1.union(set2))
print(set1 - set2)
# print(set1.difference(set2))
print(set1 ^ set2)
# print(set1.symmetric_difference(set2))
# 判断子集和超集
print(set2 <= set1)
# print(set2.issubset(set1))
print(set1 >= set2)
# print(set1.issuperset(set2))

17 字典

字典:每个元素都是由一个键和一个值组成的“键值对”,键和值通过冒号分开。

scores = {'骆昊': 95, '白元芳': 78, '狄仁杰': 82}
# 通过键可以获取字典中对应的值
print(scores['骆昊'])
# 对字典进行遍历(遍历的其实是键再通过键取对应的值)
for elem in scores:
   print('%s\t--->\t%d' % (elem, scores[elem]))
# 更新字典中的元素
scores['白元芳'] = 65
scores.update(冷面=67, 方启鹤=85)
if '武则天' in scores:
   print(scores['武则天'])
print(scores.get('武则天'))
# get方法也是通过键获取对应的值但是可以设置默认值
print(scores.get('武则天', 60))
# 删除字典中的元素
print(scores.popitem())
print(scores.pop('骆昊', 100))
# 清空字典
scores.clear()

18 类!!!

类:定义类用关键字 class(首字母小写)。

class Student(object):
    # __init__是一个特殊方法用于在创建对象时进行初始化操作
    # 通过这个方法我们可以为学生对象绑定name和age两个属性
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def study(self, course_name):
        print('%s正在学习%s.' % (self.name, course_name))

    # PEP 8要求标识符的名字用全小写多个单词用下划线连接
    # 但是部分程序员和公司更倾向于使用驼峰命名法(驼峰标识)
    def watch_movie(self):
        if self.age < 18:
            print('%s只能观看《熊出没》.' % self.name)
        else:
            print('%s正在观看岛国爱情大电影.' % self.name)

通过以下方式创建对象并向对象发消息。

stu1 = Student('骆昊', 38)
stu1.study('Python程序设计')
stu1.watch_movie()
stu2 = Student('王大锤', 15)
stu2.study('思想品德')
stu2.watch_movie()

在Python中,属性和方法的访问权限只有公开和私有,如果希望属性私有,用两个下划线作为开头命名即可。

class Test:
    def __init__(self, foo):
        self.__foo = foo
    def __bar(self):
        print(self.__foo)

注意:实际开发中我们并不建议将属性设置为私有,因为这会导致子类无法访问(后面会讲),所以大多数Python程序员会遵循一种命名惯例,就是让属性名以单下划线开头来表示属性是受保护的,本类之外的代码在访问这样的属性时应该要保持慎重。这种做法并不是语法上的规则,单下划线开头的属性和方法外界仍然是可以访问的,所以更多的时候它是一种暗示或隐喻。

19 @property装饰器

虽然不建议将属性设为私有,但如果直接将属性暴露给外界也是有问题的,比如我们没有办法检查赋给属性的值是否有效。前面建议将属性命名以单下划线开头,暗示属性是受保护的,不建议外界直接访问,那么如果想访问属性可以通过属性的getter(访问器)和setter(修改器)方法进行对应的操作。如要做到这点,就可以考虑使用@property包装器来包装getter和setter方法,使得对属性的访问既安全又方便。

class Person(object):
    def __init__(self, name, age):
        self._name = name
        self._age = age    
    # 访问器 - getter方法
    @property
    def name(self):
        return self._name
    @property
    def age(self):
        return self._age    
    # 修改器 - setter方法
    @age.setter
    def age(self, age):
        self._age = age    
    def play(self):
        if self._age <= 16:
            print('%s正在玩纸飞机。' % self._name)
        else:
            print('%s正在玩下象棋。' % self._name)
def main():
    person = Person('小明', 12)
    person.play()
    person.age = 22
    person.play()
    # person.name = '白元芳' #AttributeError: can't set attribute
    
if __name__ == '__main__':
    main()

20 __slots__

Python是一门动态语言——通常,动态语言允许我们在程序运行时给对象绑定新的属性或方法,也可以对已绑定的属性和方法进行解绑。但如果我们需要限定自定义类型的对象只能绑定某些属性,可以通过在类中定义__slots__变量来进行限定。注意__slots__的限定只对当前类的对象生效,对子类并不起任何作用。

在定义类的第一行加上这句话:

__slots__ = ('_name', '_age', '_gender')

然后尝试在类的外面给类追加'_gender'和''_address''看看效果,后者会报错。

person._address= 'man' # AttributeError: 'Person' object has no attribute '_is_gay'

21 静态方法和类方法

之前我们定义的都是对象方法(给对象发消息),实际上类中的方法并非都是对象方法,例如我们定义一个“三角形”类,通过传入三个边长来构造三角形,但是传入的三条边长未必能构造出三角形对象,因此我们可以先写一个方法来验证三条边长是否可以构成三角形,这个方法显然不是对象方法,因为在调用这个方法时三角形对象尚未创建出来(因为都不知道三条边能不能构成三角形),所以说,该方法属于三角形类但并不属于三角形对象。此时可以使用静态方法(@staticmethod)来解决这类问题。

class Triangle(object): ... ... @staticmethod def is_valid(a, b, c): return a + b > c and b + c > a and a + c > b ... ... def main(): ... ... # 静态方法和类方法都是通过给类发消息来调用的 if Triangle.is_valid(a, b, c): ... ... else: print('无法构成三角形.') ... ...

22 类方法

Python还可以在类中定义类方法(@classmethod),第一个参数约定名为cls,代表当前类相关的信息的对象(类本身也是一个对象,有的地方也称之为类的元数据对象),可以通过这个参数获取和类相关的信息并且可以创建出类的对象。

class Triangle(object):
    ... ...
    @staticmethod
    def is_valid(a, b, c):
        return a + b > c and b + c > a and a + c > b
    ... ...

def main():
    ... ...
    # 静态方法和类方法都是通过给类发消息来调用的
    if Triangle.is_valid(a, b, c):
        ... ...
    else:
        print('无法构成三角形.')
... ...

23 继承和多态

继承——提供继承信息的称之为父类(也叫超类或基类),得到继承信息的为子类(也叫派生类或衍生类)。子类除了继承父类的属性和方法,还可以自定义特有的属性和方法,所以子类比父类拥有的更多的能力。

from time import time, localtime, sleep
class Clock(object):
    """数字时钟"""
    def __init__(self, hour=0, minute=0, second=0):
        self._hour = hour
        self._minute = minute
        self._second = second
    @classmethod
    def now(cls):
        ctime = localtime(time())
        return cls(ctime.tm_hour, ctime.tm_min, ctime.tm_sec)  
    def run(self):
        """走字"""
        self._second += 1
        if self._second == 60:
            self._second = 0
            self._minute += 1
            if self._minute == 60:
                self._minute = 0
                self._hour += 1
                if self._hour == 24:
                    self._hour = 0
    def show(self):
        """显示时间"""
        return '%02d:%02d:%02d' % \
               (self._hour, self._minute, self._second)
def main():
    # 通过类方法创建对象并获取系统时间
    clock = Clock.now()
    while True:
        print(clock.show())
        sleep(1)
        clock.run()
if __name__ == '__main__':
    main()

多态——子类继承父类后可以对父类的方法进行重写。当调用子类重写的方法时,不同的子类对象会表现出不同的行为,这就是就是多态。

class Person(object):
    ... ...
class Student(Person):
    ... ...
class Teacher(Person):
    ... ...
def main():
    stu = Student('王大锤', 15, '初三')
    stu.study('数学')
    t = Teacher('骆昊', 38, '老叫兽')
    t.teach('Python程序设计')
... ...

抽象类——上例中,我们将Pet类处理成了一个抽象类,所谓抽象类就是不能够创建对象的类,这种类的存在就是专门为了让其他类去继承它。Python从语法层面并没有像Java或C#那样提供对抽象类的支持,但是我们可以通过abc模块的ABCMeta元类和abstractmethod包装器来达到抽象类的效果,如果一个类中存在抽象方法那么这个类就不能够实例化(创建对象)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值