有基础学Python > 0x5 模块

学习“廖雪峰的官方网站: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()

猜你喜欢

转载自blog.csdn.net/qq_33067925/article/details/120424709
今日推荐