美文网首页
Python 学习笔记 - 第七天

Python 学习笔记 - 第七天

作者: 罗佳欣 | 来源:发表于2018-07-04 16:55 被阅读0次

    1.作用域和命名空间

    示例: 如何引用不同作用域和命名空间

    def scope_test():
        def do_local():
            spam = "local spam"
        def do_nonlocal():
            nonlocal spam
            spam = "nonlocal spam"
        def do_global():
            global spam
            spam = "global spam"
        spam = "test spam"
        do_local()
        print("After local assignment:", spam)
        do_nonlocal()
        print("After nonlocal assignment:", spam)
        do_global()
        print("After global assignment:", spam)

    scope_test()
    print("In global scope:", spam)

    输出:

    After local assignment: test spam
    After nonlocal assignment: nonlocal spam
    After global assignment: nonlocal spam
    In global scope: global spam

    2.初识类

    2.1.类定义语法

    类定义最简单的形式:

    class ClassName:
        <statement-1>
        .
        .
        .
        <statement-N>
    2.2.类对象

    类对象支持两种操作: 属性引用和实例化

    class MyClass:
        """A simple example class"""
        i = 12345
        def f(self):
            return 'hello world'

    可以使用MyClass.iMyClass.f返回一个整数和一个方法对象.
    也可以对类属性赋值, MyClass.i = 123.
    __doc__也是一个有效的属性.

    类的实例化使用函数符号, 创建一个新的类实例并赋值给局部变量x:

    x = MyClass()

    构造方法:

    def __init__(self):
        self.data = []

    如果类定义了__init__方法的话, 类的实例化操作会自动为新的实例调用__init__()方法

    __init__()方法可以加上参数:

    >>> class Complex:
    ...     def __init__(self, realpart, imagpart):
    ...         self.r = realpart
    ...         self.i = imagpart
    ...
    >>> x = Complex(3.0-4.5)
    >>> x.r, x.i
    (3.0-4.5)
    2.3.实例对象

    数据属性相当于实例变量..
    不需要声明, 第一次使用的时候就会生成.

    x.counter = 1
    while x.counter < 10:
        x.counter = x.counter * 2
    print(x.counter)
    del x.counter

    方法是属于一个对象的函数.

    2.4.方法对象

    通常使用这种方式调用方法:

    x.f()

    x.f是一个方法对象, 可以复制给一个局部变量:

    xf = x.f
    while True:
        print(xf())
    2.5.类和实例变量

    实例变量对每一个实例来说, 都有自己唯一的数据.

    class Dog:

        kind = 'canine'

        def __init__(self, name):
            self.name = name

    >>> d = Dog('Fido')
    >>> e = Dog('Buddy')
    >>> d.kind
    'canine'
    >>> e.kind
    'canine'
    >>> d.name
    'Fido'
    >>> e.name
    'Buddy'

    若类的属性为可变对象, 如列表和字典, 可能会带来意外的效果:

    class Dog:

        tricks = []

        def __init__(self, name):
            self.name = name

        def add_trick(self, trick):
            self.tricks.append(trick)

    >>> d = Dog('Fido')
    >>> e = Dog('Buddy')
    >>> d.add_trick('roll over')
    >>> e.add_trick('play dead')
    >>> d.tricks
    ['roll over''play dead']

    这个类设计时应该使用一个实例变量:

    class Dog:

        def __init__(self, name):
            self.name = name
            self.tricks = []

        def add_trick(self, trick):
            self.tricks.append(trick)

    >>> d = Dog('Fido')
    >>> e = Dog('Buddy')
    >>> d.add_trick('roll over')
    >>> e.add_trick('play dead')
    >>> d.tricks
    ['roll over']
    >>> e.tricks
    ['play dead']

    3.一些说明

    数据属性会覆盖同名的方法属性…
    所以为了避免这种情况, 有一些约定:

    • 大写方法名称的首字母

    • 使用一个唯一的小字符串座位数据属性名称的前缀

    • 方法使用动词, 属性使用名称..

    函数定义代码不一定非得定义在类中:
    也可以将一个函数对象复制给类中的一个局部变量:

    def f1(self, x, y):
        return min(x, x+y)

    class C:
        f = f1
        def g(self):
            return 'hello world'
        h = g

    通过self参数的方法属性, 方法可以调用其他的方法:

    class Bag:
        def __init__(self):
            self.data = []
        def add(self, x):
            self.data.append(x)
        def addtwice(self, x):
            self.add(x)
            self.add(x)

    获取对象的类(class):

    object.__class__

    4.继承

    继承示例:

    class DerivedClassName(BaseClassName):
        <statement-1>
        .
        .
        .
        <statement-N>

    基类在另一个模块中时:

    class DerivedClassName(modname.BaseClassName):

    两个用于继承的函数:

    • isinstance()用于检查实例类型:isinstance(obj, int)只有在obj.class是 int 或其他从 int 继承的类型时返回 true.

    • issubclass()用于检查类继承:issubclass(bool, int)为 true, 因为 bool 是 int 的子类.issubclass(float, int)为 False, 因为 float 不是 int 的子类.

    4.1.多继承

    多继承的类定义示例:

    class DerivedClassName(Base1, Base2, Base3):
        <statement-1>
        .
        .
        .
        <statement-N>

    5.私有变量

    python 不存在只能从内部访问的私有变量.
    当以一个下划线开头的命名将会被处理为Api的非公开部分.
    当以至少两个下划线开头命名(并且后面至多一个下划线), 例如: __spam将被替换成_classname__spam.
    示例:

    class Mapping:
        def __init__(self, iterable):
            self.items_list = []
            self.__update(iterable)

        def update(self, iterable):
            for item in iterable:
                self.items_list.append(item)

        __update = update

    class MappingSubclass(Mapping):

        def update(self, keys, values):
            for item in zip(keys, values):
                self.items_list.append(item)

    6.补充

    用一个空的类定义可以实现类似 C 中的结构(struct):

    class Employee:
        pass

    john = Employee()

    john.name = 'John Doe'
    john.dept = 'computer lab'
    john.salary = 1000

    7.异常也是类

    异常抛出形式:

    raise Class

    raise Instance

    raise Class()

    异常类继承示例:

    class B(Exception):
        pass
    class C(B):
        pass
    class D(C):
        pass

    for cls in [B, C, D]:
        try:
            raise cls()
        except D:
            print("D")
        except C:
            print("C")
        except B:
            print("B")

    将按顺序打印 B, C, D.
    若将异常子句的顺序颠倒过来, 将打印 B, B, B.

    8.迭代器

    大多数容器对象都可以用 for 遍历:

    for element in [123]:
        print(element)
    for element in (123):
        print(element)
    for key in {'one':1'two':2}:
        print(key)
    for char in "123":
        print(char)
    for line in open("myfile.txt"):
        print(line, end='')

    for 遍历的工作原理:

    >>> s = 'abc'
    >>> it = iter(s)
    >>> it
    <iterator object at 0x00A1DB50>
    >>> next(it)
    'a'
    >>> next(it)
    'b'
    >>> next(it)
    'c'
    >>> next(it)
    Traceback (most recent call last):
      File "<stdin>", line 1in ?
        next(it)
    StopIteration

    给自己的类添加迭代器行为:

    class Reverse:
        """Iterator for looping over a sequence backwards."""
        def __init__(self, data):
            self.data = data
            self.index = len(data)
        def __iter__(self):
            return self
        def __next__(self):
            if self.index == 0:
                raise StopIteration
            self.index = self.index - 1
            return self.data[self.index]
    >>> rev = Reverse('spam')
    >>> iter(rev)
    <__main__.Reverse object at 0x00A1DB50>
    >>> for char in rev:
    ...     print(char)
    ...
    m
    a
    p
    s

    9.生成器

    使用 Generator 来创建迭代器:

    def reverse(data):
        for index in range(len(data)-1-1-1):
            yield data[index]
    >>> for char in reverse('golf'):
    ...     print(char)
    ...
    f
    l
    o
    g

    生成器将自动创建__iter__()__next__()方法, 显得比较简洁.

    10.生成器表达式

    示例:

    >>> sum(i*i for i in range(10))
    285

    >>> xvec = [102030]
    >>> yvec = [753]
    >>> sum(x*y for x,y in zip(xvec, yvec))
    260

    >>> from math import pi, sin
    >>> sine_table = {x: sin(x*pi/180for x in range(091)}

    >>> unique_words = set(word  for line in page  for word in line.split())

    >>> valedictorian = max((student.gpa, student.name) for student in graduates)

    >>> data = 'golf'
    >>> list(data[i] for i in range(len(data)-1-1-1))
    ['f''l''o''g']

    相关文章

      网友评论

          本文标题:Python 学习笔记 - 第七天

          本文链接:https://www.haomeiwen.com/subject/dvxyuftx.html