Python第九章(面向对象基础--属性,继承,dir查看,内存地址,权限等等和银行账户题目,圆的面积周长)

面向对象

创造对象

示例代码:类的名字用小驼峰命名法

python 复制代码
#编写Person类
class Person():
    pass
class Cat:  #,小括号可以省略
    pass
#对象名=类名
per=Person()
c=Cat()  #小括号不能省略
print(type(per))
print(type(c))

代码结果:

<class 'main.Person'>

<class 'main.Cat'>

类的基本组成

示例代码:

python 复制代码
class School:
#类属性,定义在类中,方法外的变量
    school="北京XXX教育"
#创建初始方法,定义实例属性
    def __init__(self,xm,age):#xm,age是参数,属于局部变量
        self.name=xm #左边是实例属性,右边是局部变量,进行赋值
        self.age=age #可以相同
    #定义类的函数,称为方法,自带参数self
    def show(self):
        print(f"我叫{self.name},今年{self.age}")#运用实例属性
    #静态方法
    @staticmethod
    def sm():
        print("这是静态方法,不能调用实例属性,也不能调用实例方法")
    @classmethod
    def cm(cls):#自带cls
        print("这是类方法,不能调用实例属性,也不能调用实例方法")
#创建类的对象
 # __int__(self,xm,age):两个参数需要传入
stu=School("111",18)
print(type(stu))
#实例属性,运用对象名打点调用
print(stu.name,stu.age)
#类属性,用类名打点调用
print(School.school)
#实例方法,使用对象名打点调用
stu.show()
#静态方法
School.sm()
#类方法
School.cm()

代码结果:

<class 'main.School'>

111 18

北京XXX教育

我叫111,今年18

这是静态方法,不能调用实例属性,也不能调用实例方法

这是类方法,不能调用实例属性,也不能调用实例方法

动态绑定属性和方法

就是在类的外面书写实例属性或者实例方法

示例代码:

python 复制代码
class School:
#类属性,定义在类中,方法外的变量
    school="北京XXX教育"
#创建初始方法,定义实例属性
    def __init__(self,xm,age):#xm,age是参数,属于局部变量
        self.name=xm #左边是实例属性,右边是局部变量,进行赋值
        self.age=age #可以相同
    #定义类的函数,称为方法,自带参数self
    def show(self):
        print(f"我叫{self.name},今年{self.age}")#运用实例属性
stu=School("001",18)
stu2=School("009",18)
print(stu.name,stu.age)
print(stu2.name,stu2.age)
#为stu2动态绑定一个实例属性
stu2.gender="男"
print(stu2.name,stu2.age,stu2.gender)
#为stu2动态绑定一个实例方法
def introduce():
    print("将这个函数动态绑定给stu2")
stu2.fun=introduce #函数的一个赋值
#fun为方法和show一样
#打点调用
stu2.fun()

代码结果:

001 18

009 18

009 18 男

将这个函数动态绑定给stu2

属性设置

将方法改为属性,属性可直接赋值

示例代码:

python 复制代码
class Student:
    def __init__(self,name,gender):
        self.name=name
        self.__gender=gender
#使用@property将方法转换为属性
    @property
    def gender(self):
        return self.__gender
#将gender这个属性设置为可写属性,解决stu.gender不能直接赋值的问题
    @gender.setter
    def gender(self,value):
        if value!="男" and value!="女":
            print("性别输入错误,默认为男")
            self.__gender="男"
        else:
            self.__gender=value

stu=Student("李佳怡","女")
print(stu.name,"的年龄是",stu.gender)
stu.gender="其他"
print(stu.name,"的年龄是",stu.gender)

代码结果:

李佳怡 的年龄是 女

性别输入错误,默认为男

李佳怡 的年龄是 男

多态

示例代码:

python 复制代码
class Person:
    def eat(self):
        print("人,吃五谷杂粮")
class Cat:
    def eat(self):
        print("猫,吃鱼")
class Dog:
    def eat(self):
        print("狗,吃骨头")
def fun(obj):
    obj.eat()
per=Person()
cat=Cat()
dog=Dog()
#python的多态不关心对象数据类型,只关心对象是否有同名方法
fun(per)
fun(cat)
fun(dog)

代码结果:

人,吃五谷杂粮

猫,吃鱼

狗,吃骨头

继承

示例代码:可以继承别人的属性或者方法,,被继承的称为父类

python 复制代码
class Person:#不写括号,默认object类
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def show(self):
        print(f"我叫{self.name},今年{self.age}岁")
class Student(Person):
    def __init__(self,name,age,sno):
        super().__init__(name,age) #调用父类的初始化方法
        self.sno=sno
class Doctor(Person):
    def __init__(self,name,age,department):
        super().__init__(name,age) #调用父类的初始化方法
        self.department=department
#创建对象
stu=Student("联名卡",18,1001)
stu.show()#可以直接调用父类的方法
doctor=Doctor("藏宝阁",54,"外科")
doctor.show()

代码结果:

我叫联名卡,今年18岁

我叫藏宝阁,今年54岁

多继承

示例代码:

python 复制代码
class Fathera:
    def __init__(self,name):
        self.name=name
    def showa(self):
        print("这是父类a的方法")
class Fatherb:
    def __init__(self,age):
        self.age=age
    def showb(self):
        print("这是父类b的方法")
class Son(Fathera,Fatherb):
    def __init__(self,name,age,gender):
        Fathera.__init__(self,name)
        Fatherb.__init__(self,age)
        self.gender=gender
son=Son("李佳怡",18,"男")
son.showa()
son.showb()

代码结果:

这是父类a的方法

这是父类b的方法

方法重写

示例代码:

python 复制代码
class Person:#不写括号,默认object类
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def show(self):
        print(f"我叫{self.name},今年{self.age}岁")
class Student(Person):
    def __init__(self,name,age,sno):
        super().__init__(name,age) #调用父类的初始化方法
        self.sno=sno
    def show(self):  #改写方法名字要和父类一样
        super().show() #调用父类的show方法
        print(f"我的学号是{self.sno}")
class Doctor(Person):
    def __init__(self,name,age,department):
        super().__init__(name,age) #调用父类的初始化方法
        self.department=department

    def show(self):  # 改写方法名字要和父类一样
        # super().show()   #调用父类的show方法
        # 可以不继承父类全部重写
        print(f"我叫{self.name},今年{self.age},我的工作科室为是{self.department}")
#创建对象
stu=Student("联名卡",18,1001)
stu.show()
doctor=Doctor("藏宝阁",54,"外科")
doctor.show()

代码结果:

我叫联名卡,今年18岁

我的学号是1001

我叫藏宝阁,今年54,我的工作科室为是外科

权限控制

示例代码:

python 复制代码
class School:
#类属性,定义在类中,方法外的变量
    school="北京XXX教育"
#创建初始方法
    def __init__(self,xm,age,gender):#xm,age是参数,属于局部变量
        self._name=xm #受保护,只能子类和本类进行访问
        self.__age=age #表示私有的,只能类本身进行访问
        self.gender = gender#普通实例属性,内部,外部,子类都可以进行访问
    def _fun1(self):
        print("受保护,只能子类和本类进行访问")
    def __fun2(self):
        print("表示私有的,只能类本身进行访问")
    def show(self):
        self._fun1() #类本身访问受保护方法
        self.__fun2()#类本身访问受私有方法
        print(self._name)#受保护实例属性
        print(self.__age)#私有的实例属性
stu=School("搓麻将",18,"man")
#类的外部
print(stu._name)
# print(stu.__age)  会报错 私有,出了类的定义范围就不能用了
#调用受保护的实例方法
stu._fun1()
#stu.__fun2()  会报错 私有,出了类的定义范围就不能用了
#私有的实例方法和属性也可以访问,但是有自己的形式
print(stu._School__age)
stu._School__fun2()
print(dir(stu))  #展示出所有的属性和方法

代码结果:

搓麻将

受保护,只能子类和本类进行访问

18

表示私有的,只能类本身进行访问

['_School__age', '_School__fun2', 'class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'getstate', 'gt', 'hash', 'init', 'init_subclass', 'le', 'lt', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', '_fun1', '_name', 'gender', 'school', 'show']

查看指定对象的属性,全部方法(dir)

示例代码:

python 复制代码
class School:
#类属性,定义在类中,方法外的变量
    school="北京XXX教育"
#创建初始方法,定义实例属性
    def __init__(self,xm,age):#xm,age是参数,属于局部变量
        self.name=xm #左边是实例属性,右边是局部变量,进行赋值
        self.age=age #可以相同
    #定义类的函数,称为方法,自带参数self
    def show(self):
        print(f"我叫{self.name},今年{self.age}")#运用实例属性
stu=School("李佳怡",18)
print(dir(stu))
print(stu)#自动调用__str__方法

代码结果:

['class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'getstate', 'gt', 'hash', 'init', 'init_subclass', 'le', 'lt', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', 'age', 'name', 'school', 'show']

<main.School object at 0x00000119EB827CD0>

特殊属性

示例代码:

python 复制代码
class A:
    pass
class B:
    pass
class C(A,B):
    def __init__(self,name,age):
        self.name=name
        self.age=age
a=A()
b=B()
c=C("李佳怡",18)
print("对象a的属性字典",a.__dict__)
print("对象b的属性字典",b.__dict__)
print("对象c的属性字典",c.__dict__)
print()
print("对象a所属的类",a.__class__)
print()
print("A类的父类元组",A.__bases__)
print("C类的父类元组",C.__bases__)
print()
print("A类的父类",A.__base__)
print("C类的父类",C.__base__)#显示第一个父类,如果n个父类具有同名的方法,调用第一个父类的方法
print()
print("A类的层次结构:",A.__mro__)
print("C类的层次结构:",C.__mro__)
print()
print("A类的子类列表",A.__subclasses__())#方法,要带括号
print("B类的子类列表",B.__subclasses__())
print("C类的子类列表",C.__subclasses__())

代码结果:

对象a的属性字典 {}

对象b的属性字典 {}

对象c的属性字典 {'name': '李佳怡', 'age': 18}

对象a所属的类 <class 'main.A'>

A类的父类元组 (<class 'object'>,)

C类的父类元组 (<class 'main.A'>, <class 'main.B'>)

A类的父类 <class 'object'>

C类的父类 <class 'main.A'>

A类的层次结构: (<class 'main.A'>, <class 'object'>)

C类的层次结构: (<class 'main.C'>, <class 'main.A'>, <class 'main.B'>, <class 'object'>)

A类的子类列表 [<class 'main.C'>]

B类的子类列表 [<class 'main.C'>]

C类的子类列表 []

特殊方法

示例代码:

python 复制代码
a=10
b=20
print(dir(a))
print(a.__add__(b))
print(a.__sub__(b))
print(f"{a}<{b}?",a.__lt__(b))
print(f"{a}<={b}?",a.__le__(b))
print(f"{a}={b}?",a.__eq__(b))
print("-"*40)
print(f"{a}>{b}?",a.__gt__(b))
print(f"{a}>={b}?",a.__ge__(b))
print(f"{a}!={b}?",a.__ne__(b))
print("-"*40)
print(a.__mul__(b))#乘法
print(a.__truediv__(b))#除法
print(a.__mod__(b))#取余
print(a.__floordiv__(b))#整除
print(a.__pow__(b))#幂运算

代码结果:

['abs', 'add', 'and', 'bool', 'ceil', 'class', 'delattr', 'dir', 'divmod', 'doc', 'eq', 'float', 'floor', 'floordiv', 'format', 'ge', 'getattribute', 'getnewargs', 'getstate', 'gt', 'hash', 'index', 'init', 'init_subclass', 'int', 'invert', 'le', 'lshift', 'lt', 'mod', 'mul', 'ne', 'neg', 'new', 'or', 'pos', 'pow', 'radd', 'rand', 'rdivmod', 'reduce', 'reduce_ex', 'repr', 'rfloordiv', 'rlshift', 'rmod', 'rmul', 'ror', 'round', 'rpow', 'rrshift', 'rshift', 'rsub', 'rtruediv', 'rxor', 'setattr', 'sizeof', 'str', 'sub', 'subclasshook', 'truediv', 'trunc', 'xor', 'as_integer_ratio', 'bit_count', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

30

-10

10<20? True

10<=20? True

10=20? False


10>20? False

10>=20? False

10!=20? True


200

0.5

10

0

100000000000000000000

重写__str__方法

示例代码:

python 复制代码
class School:
#类属性,定义在类中,方法外的变量
    school="北京XXX教育"
#创建初始方法,定义实例属性
    def __init__(self,xm,age):#xm,age是参数,属于局部变量
        self.name=xm #左边是实例属性,右边是局部变量,进行赋值
        self.age=age #可以相同
    #方法重写
    def __str__(self):
        return "他具有姓名和年龄两个实例属性"

stu=School("李佳怡",18)
print(stu)#自动调用__str__方法,默认输出内存地址,修改后按修改的内容输出
#也可以手动调用
print(stu.__str__())

运行结果:

他具有姓名和年龄两个实例属性

他具有姓名和年龄两个实例属性

类的浅拷贝和深拷贝

针对于内存地址,直接赋值和浅拷贝,深拷贝各不相同

示例代码:

python 复制代码
class CPU:
    pass
class Disk:
    pass
class Computer:
    def __init__(self,cpu,disk):
        self.cpu=cpu
        self.disk=disk
cpu=CPU()
disk=Disk()
com=Computer(cpu,disk)
#变量赋值
com1=com
print(com,"子对象的内存地址:",com.cpu,com.disk)
print(com1,"子对象的内存地址:",com1.cpu,com1.disk)
print()
#类对象的浅拷贝
import copy
com2=copy.copy(com)
print(com)  #com和com2的内存地址不同,但是子对象内存地址相同
print(com2)
print(com,"子对象的内存地址:",com.cpu,com.disk)
print(com2,"子对象的内存地址:",com2.cpu,com2.disk)
print()
#深拷贝
com3=copy.deepcopy(com)#连子对象的内存空间也会重新去创建
print(com,"子对象的内存地址:",com.cpu,com.disk)
print(com3,"子对象的内存地址:",com3.cpu,com3.disk)

代码结果:(观察什么相同什么不同即可)

<main.Computer object at 0x0000020991C30190> 子对象的内存地址: <main.CPU object at 0x0000020991C30110> <main.Disk object at 0x0000020991C30150>

<main.Computer object at 0x0000020991C30190> 子对象的内存地址: <main.CPU object at 0x0000020991C30110> <main.Disk object at 0x0000020991C30150>

<main.Computer object at 0x0000020991C30190>

<main.Computer object at 0x0000020991C30210>

<main.Computer object at 0x0000020991C30190> 子对象的内存地址: <main.CPU object at 0x0000020991C30110> <main.Disk object at 0x0000020991C30150>

<main.Computer object at 0x0000020991C30210> 子对象的内存地址: <main.CPU object at 0x0000020991C30110> <main.Disk object at 0x0000020991C30150>

<main.Computer object at 0x0000020991C30190> 子对象的内存地址: <main.CPU object at 0x0000020991C30110> <main.Disk object at 0x0000020991C30150>

<main.Computer object at 0x00000209918D6F50> 子对象的内存地址: <main.CPU object at 0x0000020991C30310> <main.Disk object at 0x0000020991C30B90>

相关题目示例

计算圆的面积和周长

python 复制代码
class Circle:
    def __init__(self,r):
        self.r=r
    def get_area(self):
        return 3.14*pow(self.r,2)
    def get_perimeter(self):
        return 3.14*2*self.r
r=eval(input("请输入圆的半径"))
c=Circle(r)
area=c.get_area()
perimeter=c.get_perimeter()
print("圆的面积为:",area)
print("圆的周长为",perimeter)

代码结果:

请输入圆的半径4

圆的面积为: 50.24

圆的周长为 25.12

银行账户

python 复制代码
class Account_bank:
    def __init__(self,account_number,owner,balance):
        self.account_number=account_number
        self.owner=owner
        self.balance=balance
    def display(self):
        print(f"账号:{self.account_number}")
        print(f"户主:{self.owner}")
        print(f"账户余额:{self.balance}")

    def deposit(self):
        data=eval(input("请输入你要存多少钱:"))
        money=self.balance
        self.balance=data+money
        self.get_balance()
    def withdraw(self):
        data2=eval(input("请输入你要取多少钱:"))
        self.balance-=data2
        self.get_balance()
    def get_balance(self):
        print(f"现有余额:{self.balance}")
data_1={
    "账号":"127",
    "户主":"张三",
    "余额":4000
}
data_2={
    "账号":"124",
    "户主":"李四",
    "余额":3000
}
data_3={
    "账号":"128",
    "户主":"王五",
    "余额":6000
}
user=input("请输入你的账户:")
if user==data_1["账号"]:
    account_number=user
    owner=data_1["户主"]
    balance = data_1["余额"]
elif user==data_2["账号"]:
    account_number = user
    owner=data_2["户主"]
    balance = data_2["余额"]
else:
    account_number = data_3["账号"]
    owner=data_3["户主"]
    balance = data_3["余额"]


account=Account_bank(account_number,owner,balance)
account.display()
account.deposit()
account.withdraw()

代码结果:

请输入你的账户:127

账号:127

户主:张三

账户余额:4000

请输入你要存多少钱:100

现有余额:4100

请输入你要取多少钱:0

现有余额:4100

相关推荐
不去幼儿园43 分钟前
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
人工智能·python·算法·机器学习·强化学习
Ajiang28247353042 小时前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
幽兰的天空2 小时前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
Theodore_10225 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
网易独家音乐人Mike Zhou5 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
安静读书5 小时前
Python解析视频FPS(帧率)、分辨率信息
python·opencv·音视频
----云烟----7 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024067 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
小二·7 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic7 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端