19. 类——Python官网语法摘录

1. 类新认知

类提供了一种组合数据和功能的方法。 创建一个新类意味着创建一个新的对象 类型,从而允许创建一个该类型的新 实例 。 每个类的实例可以拥有保存自己状态的属性。 一个类的实例也可以有改变自己状态的(定义在类中的)方法。
模块属性是可以写,你可以写出 modname.the_answer = 42 。可写的属性同样可以用 del 语句删除。例如, del modname.the_answer 将会从名为 modname 的对象中移除 the_answer 属性。
在不同时刻创建的命名空间拥有不同的生存期。包含内置名称的命名空间是在 Python 解释器启动时创建的,永远不会被删除。模块的全局命名空间在模块定义被读入时创建;通常,模块命名空间也会持续到解释器退出。被解释器的顶层调用执行的语句,从一个脚本文件读取或交互式地读取,被认为是 main 模块调用的一部分,因此它们拥有自己的全局命名空间。(内置名称实际上也存在于一个模块中;这个模块称作 builtins 。)
一个函数的本地命名空间在这个函数被调用时创建,并在函数返回或抛出一个不在函数内部处理的错误时被删除。

2. global和nonlocal

global 变量生存于全局作用域;nonlocal 变量生存于外层作用域。

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. 类定义
class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>
3. 类对象
class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

doc 返回所属类的文档字符串: “A simple example class”。

4. 类实例化

类的实例化使用函数表示法。 可以把类对象视为是返回该类的一个新实例的不带参数的函数。

x = MyClass()
5. 构造函数

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) 
6. 静态成员变量
class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__(self, name):
        self.name = name    # instance variable unique to each instance

>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'
class Dog:

    tricks = []             # mistaken use of a class variable

    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                # unexpectedly shared by all dogs
['roll over', 'play dead']

正确的类设计应该使用实例变量:

class Dog:

    def __init__(self, name):
        self.name = name
        self.tricks = []    # creates a new empty list for each dog

    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']
7. 类内部定义

类不能用于实现纯抽象数据类型。 实际上,在 Python 中没有任何东西能强制隐藏数据。
任何一个作为类属性的函数都为该类的实例定义了一个相应方法。 函数定义的文本并非必须包含于类定义之内:将一个函数对象赋值给一个局部变量也是可以的。

# Function defined outside the class
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)
8. 继承

如果不支持继承,语言特性就不值得称为“类”。

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

基类定义在另一个模块中

class DerivedClassName(modname.BaseClassName):

Python有两个内置函数可被用于继承机制:
使用 isinstance() 来检查一个实例的类型: isinstance(obj, int) 仅会在 obj.class 为 int 或某个派生自 int 的类时为 True。
使用 issubclass() 来检查类的继承关系: issubclass(bool, int) 为 True,因为 bool 是 int 的子类。 但是,issubclass(float, int) 为 False,因为 float 不是 int 的子类。

9. 多重继承

class DerivedClassName(Base1, Base2, Base3):

.
.
.

10. 私有变量

带有一个下划线的名称 (例如 _spam) 应该被当作是 API 的非公有部分 ,无论函数、方法或是数据成员。

11. 方法覆盖
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   # private copy of original update() method

class MappingSubclass(Mapping):

    def update(self, keys, values):
        # provides new signature for update()
        # but does not break __init__()
        for item in zip(keys, values):
            self.items_list.append(item)
13. 空类
 class Employee:
    pass

john = Employee()  # Create an empty employee record

# Fill the fields of the record
john.name = 'John Doe'
john.dept = 'computer lab'
john.salary = 1000          
14. 迭代器
for element in [1, 2, 3]:
    print(element)
for element in (1, 2, 3):
    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 语句会在容器对象上调用 iter()。 该函数返回一个定义了 next() 方法的迭代器对象,此方法将逐一访问容器中的元素。 当元素用尽时,next() 将引发 StopIteration 异常来通知终止 for 循环。使用 next() 内置函数来调用 next() 方法。

>>> 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 1, in <module>
    next(it)
StopIteration
"""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
15. 生成器

Generator 是一个用于创建迭代器的简单而强大的工具。 它们的写法类似标准的函数,但当它们要返回数据时会使用 yield 语句。 每次对生成器调用 next() 时,它会从上次离开位置恢复执行(它会记住上次执行语句时的所有数据值)。

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() 方法。当生成器终结时,它们还会自动引发 StopIteration。

16. 生成器表达式
>>> sum(i*i for i in range(10))                 # sum of squares
285

>>> xvec = [10, 20, 30]
>>> yvec = [7, 5, 3]
>>> sum(x*y for x,y in zip(xvec, yvec))         # dot product
260

>>> 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']

————Blueicex 2020/07/20 10:18 blueice1980@126.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值