ch08面向对象程序设计

2022/10/31Python学习

一、习题答案

1、

n=2
def multiply(x,y=10):
    global n
    return x*y*n
s = multiply(10,2)
print(s)

输出:40

解析:在函数multiply函数中,是先给y赋值为10,这是指 给参数一个默认值,可以不传默认参数必须指向不变对象。

2、

【单选题】面向对象方法中,继承是指( D )。
A)一组对象所具有的相似性质
B)一个对象具有另一个对象的性质
C)各对象之间的共同性质
D)类之间共享属性和操作的机制

3、Python内置的集成开发工具是( )。

答案IDLE

4、以下不能创建字典的Python语句是()

A、dict1 = {}

B、dict2 = {2:6}

C、dict3 = {[1,2,3]: “users”}

D、dict4 = {(1,2,3): “users”}

答案:C

5、编程语言分为低级语言和高级语言两类,其中,机器语言和汇编语言属于(),Python属于()。

答案:低级语言;高级语言

6、迭代器是-一个对象,表示可迭代的数据集合,包括方法_______和_______ , 可实现迭代功能

答案:

__iter__();__next__()

7、在Python中,实例变量在类的内部通过____访问,在外部通过对象实例访问。

答案:self

8、在Python类体中,______是一个类方法,在创建对象时调用,返回当前对象的一个实例,一般无须重载该方法。______方法即构造函数(构造方法),用于执行类的实例的初始化工作,在对象创建后调用,初始化当前对象的实例,无返回值。______方法即析构函数,用于实现销毁类的实例所需的操作,例如释放对象占用的非托管资源。

答案:

__new__ __init__ __del__

9、Python语句print(1,2,3,4,5,sep=‘-’,end=‘!’)的输出结果是___。

答案:

1-2-3-4-5!

10、

for i in range(10): print(i, end=' ')

答案:

0 1 2 3 4 5 6 7 8 9 

11、

(程序填空)按下列要求对如下源程序文件中的下划线进行填空(用填空内容代替①等序号,除此之外,不能改动其它任何地方)。
x=dict(a=1,b=2,c=3,d=2,e=4,f=3)
y= #存放无重复值的新字典初始化
for key,value in x.(): #遍历字典x的键值对
for v in y.(): #遍历y的各个值
if v == value: #比较值是否相等

else:
y[key]= #y字典追加新键值对
print(y)

程序的功能是:根据已有字典x,生成一个新的字典,新字典是字典x去除重复值的键值对后的结果。

程序运行结果如下图所示:
在这里插入图片描述

答案:{}

12、编写程序,求解一元二次方程x2-10x+16=0。运行效果参见下图所示。

在这里插入图片描述

from math import sqrt 
x = (10+sqrt(10*10-4*16))/2
y = (10-sqrt(10*10-4*16))/2
print(str.format("x*x-10*x+16=0的解为:{0:2.2f},{1:2.2f}",x,y))

14、写一判素数的函数,在主函数中输入一个整数,调用该函数进行判断并输出结果。

def isPrime(x):
    flag=1
    for i in range(x/2):
        if(i%2==0):
            flag=0
            print("不是素数")
            break
    if(flag):
        print("是素数")
isPrime(5)

15、

按照下列要求,设计完成一个Python程序。具体要求如下:
1.编写函数get_birthday,参数为身份证号码,根据身份证号码获得这个人的生日,并返回列表[year,month,day]。

  1. 主程序中调用函数get_birthday,给出列表对象[‘310101199005052115’, ‘310104199607076128’,‘310117199309235133’]中的 身份证号码的生日。并在主程序中显示并输出。

  2. 程序运行结果如下图所示:

  3. 在这里插入图片描述

    listx = []
    def get_birthday(x):
        for i in range(len(x)):
            for j in range(int(x[i])):
                listx.append(x[i][6:14])
                break
        return listx
    x = ['310101199005052115', '310104199607076128','310117199309235133']
    listy = get_birthday(x)
    for i in range(len(listy)):
        print(str(x[i])+" 的生日为:"+str(listy[i]))
    

二、类和对象

2.1、面向对象的特点是封装、继承和多态

对象:某种事物的抽象(功能)抽象原则包括数据抽象过程抽象两个方面

  • 数据抽象:定义对象属性;
  • 过程抽象:定义对象操作;

封装:把客观事物抽象并封装成对象

继承:允许使用现有类的功能,并在无需重新改写原来的类的情况下,对这些功能进行扩展

**多态性:**对象可以表示多个类型的能力

类中定义的成员变量

class 类名:类体
对象的创建和使用:
anOnject=类名(参数列表)
anObject.对象函数或者anObject.对象属性

2.2、类和对象

class Person1:#定义类Person1
    pass#类体为空语句
# 测试代码
p1=Person1()
print(Person1,type(Person1),id(Person1))#  1679094677760
print(p1,type(p1),id(p1))
#<__main__.Person1 object at 0x00000186F1E6AAC0>  1679095671488

2.3、属性

2.3.1、属性(1)

  • 类中定义的成员变量
  • 实例属性
    • 通过self.变量名定义的属性

定义类Person2。定义成员变量(域)

ch08面向对象程序设计_第1张图片

2.3.2、属性(2)

  • 类属性:类本身的变量

应用实例

ch08面向对象程序设计_第2张图片

2.3.3、属性(3)

私有属性和公有属性两个下划线开头,但是不以两个下划线结束的属性是私有的(private),

其他为公共的(public)

self._sex = sex #实例保护属性 本类和子类可以访问
ch08面向对象程序设计_第3张图片

如果运行A.__name会报如下错误:

Traceback (most recent call last):
  File "E:\Python\nterm\ch09\private.py", line 12, in <module>
    A.__name  #这种是错误的,不能直接访问私有类属性
AttributeError: type object 'A' has no attribute '__name'

2.3.4、@property装饰器属性(4)

@property装饰器

def 方法名(self)

​ 代码块

通过 @property 装饰器,可以直接通过方法名来访问方法,不需要在方法名后添加一对“()”小括号

ch08面向对象程序设计_第4张图片

2.3.5、@property装饰器属性(5)

setter装饰器,deleter装饰器

ch08面向对象程序设计_第5张图片

2.3.6、@property装饰器属性(6)

  1. name = property(getname) # name 属性可读,不可写,也不能删除
  2. name = property(getname, setname,delname) #name属性可读、可写、也可删除,就是没有说明文档

ch08面向对象程序设计_第6张图片

2.4、方法

方法的声明格式如下:
def 方法名(self,[形参列参]:
	函数体
方法的调用格式如下:
对象.方法名([实参列表])
self.__name是私有属性,不能被类.属性名调用
self.name是公有属性

实例方法示例。定义Person4,创建其对象,并调用对象函数

ch08面向对象程序设计_第7张图片

2.4.1、静态方法(@staticmethod)

  • 声明属于与类的对象实例无关的方法
  • 静态方法不对特定实例进行操作,在静态方法中访问对象实例会导致错误
  • 静态方法通过装饰器@staticmethod来定义
@staticmethod
def 静态方法名([形参列表])
    函数体
  • 静态方法一般通过类名来访问,也可以通过对象实例来调用
类名.静态方法名([实参列表])

摄氏温度与华氏温度之间相互转换

# -*- coding: utf-8 -*-
# @Time : 2022/11/2 15:10
# @Author:未晞~
# @FileName: Temperatureconverter.py
# @Software: PyCharm
class TemperatureConverter:
    @staticmethod
    def c2f(t_c):
        t_c = float(t_c)
        t_f = (t_c*9/5)+32
        return t_f
    @staticmethod
    def f2c(t_f):
        t_f = float(t_f)
        t_c = (t_f-32)* 5/9
        return t_c
    # 测试代码
print("1.从摄氏温度到华氏温度:")
print("2.从华氏温度到摄氏温度:")
chice = int(input("请选择转换方向:"))
if chice==1:
    t_c = float(input("请输入摄氏温度:"))
    t_f = TemperatureConverter.c2f(t_c)
    print("华氏温度为:{0:.2f}".format(t_f))
elif chice==2:
    t_f = float(input("请输入华氏温度:"))
    t_c = TemperatureConverter.f2c(t_f)
    print("摄氏温度为:{0:.2f}".format(t_c))
else:
    print("无此选项,请选择1或2")

ch08面向对象程序设计_第8张图片

实例二

ch08面向对象程序设计_第9张图片

2.4.2、类方法(@classmethod)

允许声明属于类本身的方法,即类方法

类方法不对特定实例进行操作,在类方法中访问对象实例属性会导致错误

类方法通过装饰器@classmethod来定义,第一个形式参数必须为类对象本身,通常为cls

@classmethod
def 类方法名(cls,[形参列参])
     函数体

类方法一般通过类名来访问,也可通过对象实例来调用

类名.类方法名([实参列参])
# -*- coding: utf-8 -*-
# @Time : 2022/11/2 15:31
# @Author:未晞~
# @FileName: 类方法.py
# @Software: PyCharm
class Foo:
    classnane="Foo"
    def __init__(self,name):
        self.name = name
    def f1(self):#实例方法
        print(self.name)
    @staticmethod
    def f2():#静态方法
        print("static")
    @classmethod
    def f3(cls):#类方法
        print(cls.classnane)
    # 测试代码
f = Foo("孙")
f.f1()
Foo.f2()
Foo.f3()

实验结果如下:

ch08面向对象程序设计_第10张图片

2.4.3、

_init__方法(构造函数)和__new__方法

__init__方法即构造函数(构造方法),用于执行类的实例的初始化工作。创建完对象后调用,初始化当前对象的实例,无返回值

__new__方法是一个类方法,创建对象时调用,返回当前对象的一个实例,一般无需重载该方法

__del__方法即析构函数(析构方法),用于实现销毁类的实例所需的操作,如释放对象占用的非托管资源(例如:打开的文件、网络连接等)

默认情况下,当对象不再被使用时,__del__方法运行,由于Python解释器实现自动垃圾回收,即无法保证这个方法究竟在什么时候运行

通过del语句,可以强制销毁一个对象实例,从而保证调用对象实例的__del__方法

2.4.4、私有方法示例

# -*- coding: utf-8 -*-
# @Time : 2022/11/2 15:59
# @Author:未晞~
# @FileName: 私有方法示例.py
# @Software: PyCharm
class Book:
    def __init__(self,name,author,price):
        self.name = name
        self.author = author
        self.price = price
    def __check_name(self):#定义私有方法,判断name是否为空
        if self.name == '':return False
        else:return True
    def get_name(self):#定义类Book的方法get_name
        if self.__check_name():#调用私有方法
            print(self.name,self.author)
        else:
            print('No value')
b = Book('Python程序设计','sun',18.0) #创建对象
b.get_name() #调用对象的方法
# b.__check_name() 直接调用私有方法,非法

ch08面向对象程序设计_第11张图片

2.5、方法重载

可以定义多个重名的方法,只要保证方法签名是唯一的

方法签名包括三个部分:方法名、参数数量和参数类型

# -*- coding: utf-8 -*-
# @Time : 2022/11/2 16:08
# @Author:未晞~
# @FileName: Person21Overload.py
# @Software: PyCharm
class Person21:                #定义类Person21
    def say_hi(self, name=None): #定义类方法say_hi
        self.name = name #把参数name赋值给self.name,即成员变量name(域)
        if name==None: print('您好! ')
        else: print('您好, 我叫', self.name)
p21 = Person21()       #创建对象
p21.say_hi()           #调用对象的方法,无参数
p21.say_hi('未晞~')     #调用对象的方法,带参数

ch08面向对象程序设计_第12张图片

2.6、继承

派生类:Python支持多重继承,即一个派生类可以继承多个基类

class 派生类名(基类1,[基类2,...])
     类体
     

声明派生类时,必须在其构造函数中调用基类的构造函数

基类名.__init__(self,参数列表)
# -*- coding: utf-8 -*-
# @Time : 2022/11/2 16:13
# @Author:未晞~
# @FileName: 派生类.py
# @Software: PyCharm
class Person:                 #基类
    def __init__(self, name, age): #构造函数
        self.name = name     #姓名
        self.age = age        #年龄
    def say_hi(self):         #定义基类方法say_hi
        print('您好, 我叫{0}, {1}岁'.format(self.name,self.age))
class Student(Person):         #派生类
    def __init__(self, name, age, stu_id): #构造函数
        Person.__init__(self, name, age) #调用基类构造函数
        self.stu_id = stu_id    #学号
    def say_hi(self):          #定义派生类方法say_hi
        Person.say_hi(self)    #调用基类方法say_hi
        print('我是学生, 我的学号为:', self.stu_id)
p1 = Person('未晞!', 18)            #创建对象
p1.say_hi()
s1 = Student('令', 20, '2002') #创建对象
s1.say_hi()

ch08面向对象程序设计_第13张图片

@functools.total_ordeing装饰器

  • 支持大小比较的对象需要实现特殊方法:
# -*- coding: utf-8 -*-
# @Time : 2022/11/2 16:15
# @Author:未晞~
# @FileName: tool.py
# @Software: PyCharm
import functools
@functools.total_ordering
class Student:
    def __init__(self, firstname, lastname):  #姓和名
        self.firstname = firstname
        self.lastname = lastname
    def __eq__(self, other):     #判断姓名是否一致
        return ((self.lastname.lower(), self.firstname.lower()) ==
                (other.lastname.lower(), other.firstname.lower()))
    def __lt__(self, other):     #self姓名
        return ((self.lastname.lower(), self.firstname.lower()) <
                (other.lastname.lower(), other.firstname.lower()))
#测试代码
if __name__ == '__main__':
    s1 = Student('Mary','Clinton')
    s2 = Student('Mary','Clinton')
    s3 = Student('Charlie','Clinton')
    print(s1==s2)#True
    print(s1>s3)#True

3、深拷贝、浅拷贝

  • 浅拷贝,指的是重新分配一块内存创建一个新的对象,但里面的元素是原对象中各个子对象的引用
  • 深拷贝,是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联

你可能感兴趣的:(Python,小白,java,python,开发语言)