目录
模块
-
使用模块
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
' a test module '
__author__ = 'Michael Liao'
import sys
def test():
args = sys.argv
if len(args)==1:
print('Hello, world!')
elif len(args)==2:
print('Hello, %s!' % args[1])
else:
print('Too many arguments!')
if __name__=='__main__':
test()
"""
第1行和第2行是标准注释
第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行
第2行注释表示.py文件本身使用标准UTF-8编码
第4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释
第6行使用__author__变量把作者写进去
最后两行:
当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__
而如果在其他地方导入该hello模块时,if判断将失败
因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试
"""
-
变量作用域
- 类似
__xxx__
这样的变量是特殊变量,可以被直接引用,但是有特殊用途 - 类似
_xxx
和__xxx
这样的函数或变量就是非公开的(private),不应该被直接引用
- 类似
-
安装第三方模块
- 安装第三方模块,是通过包管理工具pip,例如,pip install Pillow
- 使用清华源 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple +模块名
- 用pip一个一个安装费时费力,还需要考虑兼容性,推荐直接使用Anaconda
-
模块搜索路径
- 当我们试图加载一个模块时,Python会在指定的路径下搜索对应的.py文件,如果找不到,就会报错
- 默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在
sys
模块的path
变量中,sys.path - 我们要添加自己的搜索目录,有两种方法:
- 一是直接修改
sys.path
,添加要搜索的目录,这种方法是在运行时修改,运行结束后失效。sys.path.append('/Users/michael/my_py_scripts')
- 二是设置环境变量
PYTHONPATH。
设置方式与设置Path环境变量类似
- 一是直接修改
面向对象编程
-
类与实例
- 类名通常是大写开头
__init__
方法,第一个参数永远是self
,表示创建的实例本身,在创建实例之后,就把属性绑上去。- 数据封装。将数据和逻辑被“封装”起来
- 调用很容易,但却不用知道内部实现的细节
- 另一个好处是可以给类增加新的方法
-
访问限制
- 以
__
开头,就变成了一个私有变量(private),无法从外部访问实例变量.__name
- 需要获取私有变量可以增加,set和get方法。这样可以对参数做检查,避免传入无效的参数
- 变量名类似
__xxx__
的,是特殊变量,特殊变量是可以直接访问的 _name
,这样的实例变量外部是可以访问的,但是一般表示不访问
- 以
class Student(object):
...
def get_name(self):
return self.__name
def set_score(self,value):
self.__score = value
"""
双下划线开头的实例变量
不能直接访问__name是因为
Python解释器对外把__name变量改成了_Student__name
仍然可以通过_Student__name来访问__name变量
"""
-
继承和多态
- 当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)
- 多态。
class Animal(object):
def run(self):
print('Animal is running...')
class Dog(Animal):
pass
class Cat(Animal):
pass
c = Dog()
"""
c不仅仅是Dog,c还是Animal,这就是多态
"""
def run_twice(animal):
animal.run()
animal.run()
"""
多态的好处就是
当我们需要传入Dog、Cat、Tortoise……时,我们只需要接收Animal类型就可以了
因为Dog、Cat、Tortoise……都是Animal类型,调用方只管调用,不管细节
这就是著名的“开放封闭”原则:
对扩展开放:允许新增Animal子类;
对修改封闭:不需要修改依赖Animal类型的run_twice()等函数
"""
-
静态语言 vs 动态语言
- 对于静态语言(例如Java)。如果需要传入
Animal
类型,则传入的对象必须是Animal
类型或者它的子类 - Python这样的动态语言来说,则不一定需要传入
Animal
类型。我们只需要保证传入的对象有一个run()
方法就可以
- 对于静态语言(例如Java)。如果需要传入
这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个
read()
方法,返回其内容。但是,许多对象,只要有read()
方法,都被视为“file-like object“。许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了read()
方法的对象。
-
获取对象信息
- 判断对象类型,使用
type()
函数 - 判断对象类型,使用isinstance()
- 获得一个对象的所有属性和方法,可以使用
dir()
函数
- 判断对象类型,使用
-
实例属性和类属性
- 类属性,这个属性虽然归类所有,但类的所有实例都可以访问
- 实例属性只能由实例访问