Python:第9章面向对象程序设计 课后习题

您所在的位置:网站首页 关于self的说法不正确的是 Python:第9章面向对象程序设计 课后习题

Python:第9章面向对象程序设计 课后习题

2024-07-01 21:39| 来源: 网络整理| 查看: 265

《Python语言程序设计》刘卫国主编,中国工信出版集团,电子工业出版社

习题9

一、选择题

1.下列说法中不正确的是(      )。D

A.类是对象的模板,而对象是类的实例

B.实例属性名如果以__开头,就变成了一个私有变量

C.只有在类的内部才可以访问类的私有变量,外部不能访问

D.在Python中,一个子类只能有一个父类

2.下列选项中不是面向对象程序设计基本特征的是(      )。C

A.继承          B.多态           C.可维护性         D.封装

3.在方法定义中,访问实例属性x的格式是(      )。B

A.x         B.self.x      C.self[x]       D.self.getx()

4.下列程序的执行结果是(      )。D

class Point:     x=10     y=10     def __init__(self,x,y):         self.x=x         self.y=y pt=Point(20,20) print(pt.x,pt.y)

A.10 20         B.20 10      C.10 10       D.20 20

5.下列程序的执行结果是(      )。A

class C():       f=10 class C1(C):     pass print(C.f,C1.f)

A.10 10         B.10 pass      C.pass 10       D.运行出错

二、填空题

1.在Python中,定义类的关键字是        。class

2.类的定义如下:

class person:     name='Liming'     score=90

该类的类名是        ,其中定义了        属性和        属性,它们都是        属性。如果在属性名前加两个下划线(__),则属性是        属性。将该类实例化创建对象p,使用的语句为        ,通过p来访问属性,格式为        、        。

person,name,score,公有,私有,p=person(),p.name,p.score

3.Python类的构造方法是        ,它在        对象时被调用,可以用来进行一些属性        操作;类的析构方法是        , 它在        对象时调用,可以进行一些释放资源的操作。__init__,生成,初始化,__del__,释放

4.可以从现有的类来定义新的类,这称为类的      ,新的类称为        ,而原来的类称为        、父类或超类。继承,子类,基类

5.创建对象后,可以使用       运算符来调用其成员。.

6.下列程序的运行结果为       。100

class Account:     def __init__(self,id):         self.id=id         id=888 acc=Account(100) print(acc.id)

7.下列程序的运行结果为       。100 100

class parent:    def __init__(self,param):        self.v1=param class child(parent):    def __init__(self,param):        parent.__init__(self,param)        self.v2=param obj=child(100) print(obj.v1,obj.v2)

8.下列程序的运行结果为      。400

class account:     def __init__(self,id,balance):         self.id=id         self.balance=balance     def deposit(self,amount):         self.balance+=amount     def withdraw(self,amount):         self.balance-=amount acc1=account('1234',100) acc1.deposit(500) acc1.withdraw(200) print(acc1.balance)

三、问答题

1.什么叫类?什么叫对象?它们有何关系?

( 1)对象是一个实体,这个实体具有明确定义的边界和标识,并且封装了状态和行为;

( 2)类就是对象的抽象描述,这些对象共享相同的属性、操作、关系和语义。

( 3) 类是对象的抽象,而对象是类的实例,是具体的;通过类可以构造具体的对象。

2.在Python中如何定义类与对象?

类是一种广义的数据类型,这种数据类型中的元素(或成员)既包含数据,也包含操作数据的函数。在Python 中,通过class 关键字来定义类。定义类的一般格式如下:

class 类名: 类体

类是抽象的,要使用类定义的功能,就必须将类实例化,即创建类的对象。在Python 中,用赋值的方式创建类的实例,一般格式为:

对象名=类名(参数列表)

创建对象后,可以使用“.”运算符,通过实例对象来访问这个类的属性和方法(函数),一般格式为: 

对象名.属性名 对象名.函数名()

3.类的属性有哪几种?如何访问它们?

一般情况下5261,属性访问的默认行为是从对象的字典中4102获取,并当获取不到时会1653沿着一定的查找链进行查找。例如 a.x 的查找链就是,从 a.__dict__['x'] ,然后是 type(a).__dict__['x'] ,再通过 type(a) 的基类开始查找。

若查找链都获取不到属性,则抛出 AttributeError 异常。

一、__getattr__ 方法

这个方法是当对象的属性不存在是调用。如果通过正常的机制能找到对象属性的话,不会调用 __getattr__ 方法。

class A:

a = 1

def __getattr__(self, item):

print('__getattr__ call')

return item

t = A()

print(t.a)

print(t.b)

# output

1

__getattr__ call

b

二、__getattribute__ 方法

这个方法会被无条件调用。不管属性存不存在。如果类中还定义了 __getattr__ ,则不会调用 __getattr__()方法,除非在 __getattribute__ 方法中显示调用__getattr__() 或者抛出了 AttributeError 。

class A:

a = 1

def __getattribute__(self, item):

print('__getattribute__ call')

raise AttributeError

def __getattr__(self, item):

print('__getattr__ call')

return item

t = A()

print(t.a)

print(t.b)

所以一般情况下,为了保留 __getattr__ 的作用,__getattribute__() 方法中一般返回父类的同名方法:

def __getattribute__(self, item):

return object.__getattribute__(self, item)

使用基类的方法来获取属性能避免在方法中出现无限递归的情况。

三、__get__ 方法

这个方法比较简单说明,它与前面的关系不大。

如果一个类中定义了 __get__(), __set__() 或 __delete__() 中的任何方法。则这个类的对象称为描述符。

class Descri(object):

def __get__(self, obj, type=None):

print("call get")

def __set__(self, obj, value):

print("call set")

class A(object):

x = Descri()

a = A()

a.__dict__['x'] = 1 # 不会调用 __get__

a.x # 调用 __get__

如果查找的属性是在描述符对象中,则这个描述符会覆盖上文说的属性访问机制,体现在查找链的不同,而这个行文也会因为调用的不同而稍有不一样:如果调用是对象实例(题目中的调用方式),a.x 则转换为调用:。type(a).__dict__['x'].__get__(a, type(a))

如果调用的是类属性, A.x 则转换为:A.__dict__['x'].__get__(None, A)

其他情况见文末参考资料的文档

四、__getitem__ 方法

这个调用也属于无条件调用,这点与 __getattribute__ 一致。区别在于 __getitem__ 让类实例允许 [] 运算,可以这样理解:

__getattribute__适用于所有.运算符;

__getitem__适用于所有 [] 运算符。

class A(object):

a = 1

def __getitem__(self, item):

print('__getitem__ call')

return item

t = A()

print(t['a'])

print(t['b'])

如果仅仅想要对象能够通过 [] 获取对象属性可以简单的:

def __getitem(self, item):

return object.__getattribute__(self, item)

总结

当这几个方法同时出现可能就会扰乱你了。我在网上看到一份示例还不错,稍微改了下:

class C(object):

a = 'abc'

def __getattribute__(self, *args, **kwargs):

print("__getattribute__() is called")

return object.__getattribute__(self, *args, **kwargs)

# return "haha"

def __getattr__(self, name):

print("__getattr__() is called ")

return name + " from getattr"

def __get__(self, instance, owner):

print("__get__() is called", instance, owner)

return self

def __getitem__(self, item):

print('__getitem__ call')

return object.__getattribute__(self, item)

def foo(self, x):

print(x)

class C2(object):

d = C()

if __name__ == '__main__':

c = C()

c2 = C2()

print(c.a)

print(c.zzzzzzzz)

c2.d

print(c2.d.a)

print(c['a'])

可以结合输出慢慢理解,这里还没涉及继承关系呢。总之,每个以 __get 为前缀的方法都是获取对象内部数据的钩子,名称不一样,用途也存在较大的差异,只有在实践中理解它们,才能真正掌握它们的用法。

4.继承与派生有何关系?如何实现类的继承?

  继承与派生其实是同一过程从不同的角度看,我们将保持已有类的特性而构造新类的过程称为继承,说白了继承的目的就是实现原来设计与代码的重用,希望尽量利用原有的类。然而当新的问题出现,原有程序无法解决或不能完全解决时,需要对原有程序进行改造,在已有类的基础上新增自己的特性而产生新类的过程称为派生。

5.什么是多态?在Python中如何体现?

多态,指抽象类中定义的一个方法,可以在其子类中重新实现,不同子类中的实现方法也不相同。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3