红魔咖啡馆

头发越掉越多,头发越掉越少

0%

【CS61A】CS61A——Representations

Representations

String Representations

字符串用来表达语言与程序
Python中,有两种字符串表达 - str:对人类可读 - repr:对解释器刻可读 这两种一般相同,但也有不同之处
### repr String for an Object repr函数返回一个python表达式(字符串),该表达式会评估为一个等同的对象
对一个对象的repr调用eval会给你一个与原始对象等价的对象
调用repr的结果与在python交互界面输出的结果相同

str String for an Object

str函数接受任何对象,返回一个字符串,字符串是原始对象的人类可以解释的表示
对表达式调用str的结果与调用print时输出的结果相同

F-strings

String Interpolation

字符串插值包括对一些含有表达式的字符串字面量求值 - 可以使用+进行字符串连接实现 'pi starts with'+str(pi)+'...' - 也可以使用f-string功能实现字符串插值 f'pi starts with {pi}' 花括号中的将会作为表达式看待并给出计算结果 f-string的计算结果包括str string和子表达式的值

Polymorphic Functions

多态函数是一种适用于多种数据类型的函数
如str和repr函数都是多态函数,它们接受任何类型的对象
原理:repr调用了一个零参数方法__repr__以便在参数上获取他返回的repr字符串
str同样调用一个 零参数方法__str__
对于repr函数:

  • repr函数内部只调用了一个名为repr的类属性,而实例属性__repr__被忽略了
  • 实现如下:
1
2
def repr(x):
    return type(x).__repr__(x)

对于str函数: - 实例属性__str__被忽略了 - 若类上根本没有__str__属性,则调用str只会返回repr返回的内容

Interface

对象传递信息的方式:通过互相查找属性或方法
属性的查找规则允许不同数据类型通过具有相同属性名称来响应相同信息

共享信息:在许多不同类上引起相似行为的属性名称
接口:一组共享信息与一些规范(表示其含义)

如实现__repr__与__str__的类实现了一个接口,一下是用类来展示该接口的代码

1
2
3
4
5
6
7
8
9
class Ratio:
    def __init__(self, n, d):
        self.numer = n
        self.denom = d

    def __repr__(self):
        return 'Ratio({0}, {1})'.format(self.numer, self.denom)
    def __str__(self):
        return '{0}/{1}'.format(self.numer, self.denom)

当我们令half = Ratio(1,2),直接打印half,输出为可读版本,而直接在解释器展示half,就会输出python表达式

Special Method Names

python中,以两个下划线包围的名字表示它们具有某种内置行为 - __init__:构造对象时会自动调用的方法 - __repr__:将对象以python表达式的方式输出,在交互式python界面时用于显示值的方法 - __add__:用于将一个对象加入另一个对象 - __bool__:用于将一个对象转换为布尔值 - __float__:用于将一个对象转换为实数 同时,以下代码实现了将两个对象相加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Ratio:
    def __init__(self, n, d):
        self.numer = n
        self.denom = d

    def __repr__(self):
        return 'Ratio({0}, {1})'.format(self.numer, self.denom)
    def __str__(self):
        return '{0}/{1}'.format(self.numer, self.denom)
    def __add__(self, other):
        if isinstance(other, int):
            n = self.numer+self.denom*other
            d = self.denom
        elif isinstance(other, Ratio):
            n = self.numer*other.denom +self.denom*other.numer
            d = self.denom*other.denom
        elif isinstance(other, float):
            return float(self)+other
        g = gcd(n,d)
        return Ratio(n//g, d//g)
    __radd__ = __add__

    def __float__(self):
        return self.numer/self.denom

def gcd(n, d):
    while n!=d:
        n, d = min(n, d), abs(n-d)
    return n