学习“廖雪峰的官方网站:Python教程”时做的笔记
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 一个.py文件就是一个模块(Module)。
# 为了避免模块名冲突,又引入了按目录来组织模块的方法,成为包(Package)。
# 每一个包目录下面必须有一个__init__.py文件,可以是空文件。它本身就是一个模块,模块名就是目录名。
# 创建模块时,不能和自带的模块名称冲突。
# 在命令行运行模块文件时,Python解释器把一个特殊变量__name__置为'__main__',因此可以执行一些额外的代码,如测试代码。
# '_'前缀的函数或变量是非公开的(private) ,不应该(实际却可以)被直接引用。
# Python解释器搜索包的路径存放在sys模块的path变量中。
# 添加自己的搜索目录以搜索自己的包:1.sys.append(); 2.环境变量PYTHONPATH。
# OOP
# __init__方式是构造函数。
# 类中函数第一个参数永远是self,且调用时不用传递它。
# 和静态语言不同,允许对实例变量绑定任何数据。Student1可以追加age变量,而一般的Student2却没有age变量。
# 内部属性以双下划线'__'开头就成了私有变量,解释器会把它重命名为_ClassName__xxx。
# 为什么要定义getter、setter?因为它们是方法,可以对参数做检查。
# 同时以双下划线'__'开头和结尾的特殊变量可以直接访问。
# 动态语言的鸭子类型:看起来和走起来像鸭子,那就可以看作是鸭子。保证有对应的属性和方法就可以跑通,不要求严格的继承关系。
# types模块中定义了类型常量,FunctionType、BuiltinFunctionType等。
# dir()获得对象的所有属性和方法。(get|set|has)attr()。
# len()函数内部自动调用对象的__len__()方法。
# 相同名称的实例属性将屏蔽掉类属性(被该类的所有实例共享)。
# 高级OOP
# 可以动态给 实例和类 绑定 方法和属性。
# 类中定义__slots__变量,可以规定动态绑定的属性名。对子类无效。
# @property装饰器把方法变成属性调用,该属性可以有一个对应的@xxx.setter。
# 支持多重继承。MixIn给一个类增加多个功能,类似接口类。
# __str__()返回用户看到的字符串(如print()时),__repr__()返回开发者看到的字符串(如交互调试时查看变量)。
# __iter__()返回可迭代对象,可以for、next()。
# __getitem__()可按照下标取出元素。还有__setitem__()、__delitem__()。
class Fib(object):
def __init__(self):
self.a, self.b = 0, 1
def __iter__(self):
return self # 实例本身就是迭代对象,故返回自己
def __next__(self):
self.a, self.b = self.b, self.a + self.b
if self.a > 10_000:
raise StopIteration()
return self.a
def __getitem__(self, n):
if isinstance(n, int):
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
if isinstance(n, slice):
start = n.start
stop = n.stop
if start is None:
start = 0
a, b = 1, 1
L = []
for x in range(stop):
if x >= start:
L.append(a)
a, b = b, a + b
return L
fib = Fib()
print(fib[:7])
print(fib.a, fib.b)
for fb in fib:
print(fb)
print(fib.a, fib.b) # 被上面的for循环改变了,结束时self.a > 10_000成立
print('同一个迭代对象再次for竟会啥也没有!')
for fb in fib:
print(fb)
# 当调用 不存在 的属性时,解释器才会调用__getattr__(self, xxx)尝试获得属性或函数。甚至可以实现链式调用。
class Chain(object):
def __init__(self, path=''):
self._path = path
def __getattr__(self, path):
return Chain('%s/%s' % (self._path, path))
def __str__(self):
return self._path
__repr__ = __str__
print(Chain().status.user.timeline.list) # status、user...都是不存在的属性,不断自动追加到_path后面。
# '/status/user/timeline/list'
# __call__()使 类 本身成为一个函数,甚至可以带参数。callable()判断对象是否可调用,即是否函数对象。
from enum import Enum, unique
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr'))
for name, member in Month.__members__.items():
print(name, '=>', member, ',', member.value)
# 保证没有重复值
@unique
class Weekday(Enum):
Sun = 0
Mon = 1
Sat = 6
# type
# type()既可以返回对象类型,也可以创建新类型。
# Hello = type('Hello', (object,), dict(hello = fn))
# h = Hello()
# h.hello()
# metaclass
# 最难理解也最难使用的魔术代码。
# 动态修改类定义,可以用来编写ORM框架。
# 异常
# raise ValueError()
'''
try ...
except Exception as e ...
finally ...
'''
# 断言
n = 1
assert n != 0, 'n is zero!'
# 断言n != 0失败时抛出AssertionError: n is zero!
# 命令行python -O 关闭assert,此时相当于pass。
import logging
logging.basicConfig(level = logging.INFO)
logging.info('这是logging info')
# pdb
# python -m pdb bug.py
# pdb.set_trace() 设置断点,自动在此处暂停进入单步调试。
# 测试
# unittest.main()
# doctest.testmod()