Python面向对象的30个小例子
Posted ShenLiang2025
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python面向对象的30个小例子相关的知识,希望对你有一定的参考价值。
Python面向对象30个微代码(含解释)
# 部分代码参考自网络
#0 认识对象里方法的调用
class Animal:
def run(self):
print("I can run")
a = Animal()
a.run()
#Animal.run(a) 等同于上述方法,类名.方法名传入对象为参数
#结果: I can run
# 1 创建类并生成对象
from collections import defaultdict
class Stu:
name="JohnShen"
score=80
if __name__ == '__main__':
s1= Stu()
print(s1.name+"\\t"+str(s1.score))
#结果JohnShen 80
# 2 创建一个空类
class Stu:
pass
if __name__ == '__main__':
s1 = Stu()
print(s1)
# 结果: 打印出对象的内存地址:<__main__.Stu object at 0x0000021s1DF9F5E0>>
# 3 通过type生成对象
s1 = type("Stu",(),)()
s1.name = "JohnShen"
s1.score=80
print(s1.name+"\\t"+str(s1.score))
#结果:JohnShen 80
# 4 在类方法定义及调用
class Stu:
name = "JohnShen"
score = 70
def getGrade(self):
if self.score>=60 and self.score<=80:
return "您的工资级别是中级"
elif self.score>80 and self.score<=100:
return "您的工资级别是高级"
elif self.score>100:
return "分数不合法"
else:
return "您的工资级别是低级"
if __name__ == '__main__':
s1= Stu()
print(s1.getGrade())
#结果:您的工资级别是中级
# 5 通过init方法初始话对象
class Stu:
def __init__(self,name="JohnShen",score=80):
self.name=name
self.score=score
if __name__ == '__main__':
#s1= Stu() 如果不传参数,则取默认的参数值即name="JohnShen",score=10000
s1=Stu("John","80") #指定参数name和score
print(s1.name + "\\t" + str(s1.score))
#结果:John 80
# 6 更新对象里属性
class Stu:
def __init__(self, name="JohnShen", score=80):
self.name = name
self.score = score
if __name__ == '__main__':
s1=Stu()
print("更新前:\\t"+s1.name + "\\t" + str(s1.score))
s1.score=90
print("更新后:\\t" + s1.name + "\\t" + str(s1.score))
# 更新前: JohnShen 70
# 更新后: JohnShen 90
# 7 删除对象里属性
class Stu:
def __init__(self, name="JohnShen", score=80):
self.name = name
self.score = score
if __name__ == '__main__':
s1=Stu()
print("删除前:\\t"+s1.name + "\\t" + str(s1.score))
del s1.score
print("删除后:\\t" + s1.name)
del s1
# 删除前: JohnShen 80
# 删除后: JohnShen
#对比
class Stu:
name="JohnShen"
score=90
if __name__ == '__main__':
s1=Stu() #注意因为该方式下s1类并没有定义属性,所以在执行del s1.score时会报错,同理del s1.name时也会报错
print("删除前:\\t"+s1.name + "\\t" + str(s1.score))
del s1.score
print("删除后:\\t" + s1.name)
# AttributeError: score
#8 查看对象的类型并进行对比
class Stu:
name="JohnShen"
score=90
if __name__ == '__main__':
s1=Stu()
s2=Stu()
print("s1的对象类型是:\\t"+str(type(s1)))
print(type(s1) is type(s2))
# s1的对象类型是: <class '__main__.Stu'>
# True
#9 拷贝一个对象的属性到另外个对象
class Stu:
name="JohnShen"
score=90
if __name__ == '__main__':
s1=Stu()
s2=Stu()
s1.score=100
s2.__dict__.update(s1.__dict__) #s2从s1里更新属性
print("更新后s1的分数:\\t"+str(s1.score))
print("更新后s2的分数:\\t" + str(s2.score))
# 更新后s1的分数: 100
# 更新后s2的分数: 100
#10 获取对象的属性名
class Stu:
id = 0;
def __init__(self, name="JohnShen", score=80):
self.name = name
self.score = score
def getInfo(self):
return self.name+"\\t"+str(self.score)
if __name__ == '__main__':
s1=Stu()
print( [i for i in dir(s1) if not i.startswith("__")])
# 结果: ['getInfo', 'id', 'name', 'score']
#11 遍历对象的属性及其内容
class Stu:
id = 0;
def __init__(self, name="JohnShen", score=80):
self.name = name
self.score = score
def getInfo(self):
return self.name+"\\t"+str(self.score)
if __name__ == '__main__':
s1=Stu()
#print(vars(s1))
for i in vars(s1):
#print(str(i)+"\\t"+str(vars(s1)[i]))
print("0:1".format(i,vars(s1)[i]))
# name:JohnShen
# score:80
#12 创建对象后再新增属性并赋值
class Stu:
id = 0;
def __init__(self, name="JohnShen", score=80):
self.name = name
self.score = score
def getInfo(self):
return self.name+"\\t"+str(self.score)
if __name__ == '__main__':
s1=Stu()
print(s1.name+"\\t"+str(s1.score))
s1.__setattr__("edu","本科")
setattr(s1,"addr","HF")
print(s1.name + "\\t" + str(s1.score)+"\\t"+str(s1.addr)+"\\t"+str(s1.edu))
delattr(s1,"addr")
print(s1.name + "\\t" + str(s1.score) + "\\t" + str(s1.edu))
# JohnShen 80
# JohnShen 80 HF 本科
# JohnShen 80 本科
#13 对象实例作为参数
# class Emp 有个name,id属性以及学历对象列表
# class Edu, 有个name属性
class Stu:
def __init__(self,id,name):
self.id = id
self.name = name
self.edu=[]
def addEdu(self,edu):
self.edu.append(edu)
class Edu:
def __init__(self,name):
self.name = name
if __name__ == '__main__':
s = Stu(10,'John')
for i in ('本科、研究生、博士').split("、"):
e = Edu(i)
s.edu.append(e)
for j in s.edu:
print(j.name)
#结果
#本科
#研究生
#博士
#14 自定义类实例(对象)参数的名字
class Stu:
def __init__(this,id,name):
this.id = id
this.name = name
if __name__ == '__main__':
s = Stu(10,'John')
print(s.id,s.name)
# 结果
# 10 John
#15 使用类静态变量
class Stu:
addr="hefei"
def __init__(this,id,name):
this.id = id
this.name = name
if __name__ == '__main__':
s = Stu(10,'John')
print(s.id,s.name,Stu.addr)
s.addr="nanjing"
print(s.id,s.name,Stu.addr,s.addr)
# 结果
# 10 John
#16 方法里定义类并实例化
def getExperience(des,edu = None):
class Edu:
def __init__(self,name):
self.name =name
if not edu:
e = Edu("本科")
return des+e.name
if __name__ == '__main__':
#print(getExperience("John",None))
print(getExperience("John"))
#结果:John本科
#17 计算两点之间的距离
import math
class Point:
def __init__(self,x=0,y=0):
self.x=x
self.y=y
def distance(self,p1):
return round(math.sqrt((self.x-p1.x)**2+(self.y-p1.y)**2),2)
if __name__ == '__main__':
p1 = Point(3,4)
p2 = Point(6,8)
print(p1.distance(p2))
#结果: 5.0
# 18 内置contains方法重载
class Evennums:
def __contains__(self, item):
if (not isinstance(item,int) or item%2):
return False
else:
return True
e = Evennums()
print(e.__contains__(4))
#结果:True
# 19 重构对象基本信息方法repr
class Stu:
def __init__(self,id,name):
self.id=id
self.name=name
def __repr__(self): #如果不重新则,默认是打印对象的内存地址
return "您的序号是:0,姓名是:1".format(self.id,self.name)
if __name__ == '__main__':
s = Stu(1,'JohnShen')
print(s)
#结果:您的序号是:1,姓名是:JohnShen
#20 继承与重载内置类实例
class ContactList(list):
def match(self,name):
matchResult=[]
for contact in self:
if name in contact.name:
matchResult.append(contact)
return matchResult
class Contact:
allContacts=ContactList()
def __init__(self,name,email):
self.name = name
self.email = email
Contact.allContacts.append(self)
class Supplier(Contact):
def order(self,order):
print(f"'order' order to 'self.name'")
c1 = Contact("shen","Shen@hotmail.com")
c2 = Contact("shenLiang","liang@163.com")
c3 = Contact("Liang","liang@163.com")
s = Supplier("Mike","mike@qq.com")
print([i.name for i in Contact.allContacts.match("shen")])
s.order("I need water")
#结果
#['shen', 'shenLiang']
#'I need water' order to 'mike'
#20 构造方法重写及调研父类构造方法
class Contact:
def __init__(self,id,name,email):
self.id = id
self.name = name
self.email = email
#法1
class Student(Contact):
def __init__(self,id,name,email,stuid,school):
self.id = id
self.name = name
self.email = email
self.stuid = stuid
self.school = school
#法2
class Student(Contact):
def __init__(self,id,name,email,stuid,school):
#super(Student, self).__init__(id,name,email)
super().__init__(id,name,email)
self.stuid = stuid
self.school = school
s = Student(1,"John","John@163.com",1000,"NanJing university")
print("名称:0\\t学校:1".format(s.name,s.school))
#结果:名称:John 学校:NanJing university
#21 多继承的钻石问题
class BaseClass:
basenum=0
def call_me(self):
print("call me at BaseClass")
self.basenum+=1
class LeftClass(BaseClass):
leftnum=0
def call_me(self):
BaseClass.call_me(self)
print("call me at LeftClass")
self.leftnum+=1
class RightClass(BaseClass):
rightnum=0
def call_me(self):
BaseClass.call_me(self)
print("call me at RightClass")
self.rightnum+=1
class SubClass(LeftClass,RightClass):
subnum =0
def call_me(self):
LeftClass.call_me(self)
RightClass.call_me(self)
print("call me at SubClass")
self.subnum+=1
s = SubClass()
s.call_me()
print(s.basenum,s.leftnum,s.rightnum,s.subnum)
#结果:
# call me at BaseClass
# call me at LeftClass
# call me at BaseClass
# call me at RightClass
# call me at SubClass
# 2 1 1 1
#用supper方式调用
class BaseClass:
basenum=0
def call_me(self):
print("call me at BaseClass")
self.basenum+=1
class LeftClass(BaseClass):
leftnum=0
def call_me(self):
super().call_me()
print("call me at LeftClass")
self.leftnum+=1
class RightClass(BaseClass):
rightnum=0
def call_me(self):
#BaseClass.call_me(self)
super().call_me()
print("call me at RightClass")
self.rightnum+=1
class SubClass(LeftClass,RightClass):
subnum =0
def call_me(self):
#LeftClass.call_me(self)
#RightClass.call_me(self)
super().call_me()
print("call me at SubClass")
self.subnum+=1
s = SubClass()
s.call_me() # 这里调用的是next方法,因为LeftClass的"父类"是RightClass,所以LeftClass->RightClass->BaseClass
print(s.basenum,s.leftnum,s.rightnum,s.subnum)
#结果:
# call me at BaseClass
# call me at RightClass
# call me at LeftClass
# call me at SubClass
# 1 1 1 1
#22 多继承的钻石问题
# MRO及对象继承关系分析示例
class A:
def callme(self):
print("call me at A")
class B(A):
def callme(self):
super().callme()
print("call me at B")
class C(B):
def callme(self):
super().callme()
print("call me at C")
class D(B):
def callme(self):
super().callme()
print("call me at D")
class E(C):
def callme(self):
super().callme()
print("call me at E")
class F(D):
def callme(self):
super().callme()
print("call me at F")
class G(E,F):
def callme(self):
super().callme()
print("call me at G")
g = G()
g.callme()
print(G.__mro__)
# MRO顺序,首先G继承自E,E继承自C,C继承自B,这时B又有分支(即D继承自B,F继承自D,所以C"继承"自F),B继承自A,所有顺序为
# G -> E -> C -> F -> D -> B -> A -> Object,画出树形图更直观些
#
# 结果:
# call me at A
# call me at B
# call me at D
# call me at F
# call me at C
# call me at E
# call me at G
# (<class '__main__.G'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
#
# Process finished with exit code 0
#23 __init__结合*args、**keyargs多继承使用案例,当确定构造函数里的参数时用*args、**keyargs
# 这里的*args、**keyargs即指定参数是动态传递,分别按照位置和键值对
# V1 版本1
class Human(object):
humannum=0
def __init__(self,name):
self.name = name
self.humannum+=1
class Person(Human):
personnum=0
def __init__(self,name,gender):
self.gender = gender
Human.__init__(self,name)
self.personnum+=1
class Age(Human):
agenum=0
def __init__(self,name,age):
Human.__init__(self,name)
self.age = age
self.agenum+=1
class Student(Person,Age):
stunum=0
def __init__(self,name,gender,age,school):
Person.__init__(self,name,gender)
Age.__init__(self,name,age)
self.school = school
self.stunum+=1
s = Student("john","Female",26,"NanJing University")
print(s.name,s.school)
print(s.humannum,s.personnum,s.agenum,s.stunum)
# V2 版本2
class Human:
humannum=0
def __init__(self,name,**keyargs):
self.name=name
super().__init__(**keyargs)
self.humannum+=1
class Person(Human):
personnum=0
def __init__(self,gender,**keyargs):
self.gender=gender
super().__init__(**keyargs)
self.personnum+=1
class Age(Human):
agenum=0
def __init__(self,age,**kwargs):
self.age = age
super().__init__(**kwargs)
self.agenum+=1
class Student(Person,Age):
stunum=0
def __init__(self,stuid,**kwargs):
self.stuid = stuid
super().__init__(**kwargs)
self.stunum+=1
s = Student(name="Liang",gender="Male",age=30,stuid=10000)
print(s.name,s.stuid)
print(s.humannum,s.personnum,s.agenum,s.stunum)
print(Student.__mro__)
#结果:
#Liang 10000
#1 1 1 1
#(<class '__main__.Student'>, <class '__main__.Person'>, <class '__main__.Age'>, <class '__main__.Human'>, <class 'object'>)
#24 super()__init__结合*args的案例
class Human:
def __init__(self,id,name,*args):
self.id = id
self.name = name
#super().__init__(*args)
class Person:
def __init__(self,age,*args):
self.age = age
#super().__init__(*args)
class Student(Human,Person,):
def __init__(self,*args):
super().__init__(*args)
#super(P,S).__init__(age)
#super().__init__(self,age)
s = Student("John",10,30)
print(Student.__mro__)
print(s.id,s.name,s.age)
# 结果 AttributeError: 'Student' object has no attribute 'age'
# 错误分析,因为继承顺序是 Student -> Human -> Person -> Object,而Human里并未定义调用父类的方法,所有无法读取age属性
# 解决方法,这里打开Human和Person里的#super().__init__(*args)注释即可。
#25 动态参数*args和**keyargs案例
def dynamic_args(*args,**keyargs): #位置参数(tuple)和关键字参数(dic)
print(f'type(args)\\targs')
print(f'type(keyargs)\\tkeyargs')
if __name__ == '__main__':
dynamic_args(8,9,11,name="john",addr="hefei")
a = 100
b = 200
c = 400
d = 'name':'john','addr':'hefei'
dynamic_args(a,b,c,**d) #注意 用**keyargs参数时变量前也得加上**,即传成**d
#结果:
# <class 'tuple'> (8, 9, 11)
# <class 'dict'> 'name': 'john', 'addr': 'hefei'
# <class 'tuple'> (100, 200, 400)
# <class 'dict'> 'name': 'john', 'addr': 'hefei'
#26 动态指定对象属性并赋值
class Person():
def __init__(self, name, gender, **kwargs):
super().__init__() #注意继承自Object的不用**kwargs参数,否则报错TypeError: object.__init__() takes exactly one argument (the instance to initialize)
self.name = name
self.gender = gender
for k, v in kwargs.items():
setattr(self, k, v)
p = Person('Bob', 'Male', age=18, course='Python',edu="bachelor")
print (p.age,p.course)
print([ i for i in dir(p) if not i.startswith('__')])
#27 对象类的__init__只有一个参数 TypeError: object.__init__() takes exactly one argument (the instance to initialize)
class Animal:
def __init__(self,**kwargs):
#super().__init__(**kwargs) #因为改类继承自object,而对象类只能有1个参数,所以不能加**kwargs参数
super().__init__()
for k, v in kwargs.items():
setattr(self, k, v)
a= Animal(name="Wolf")
print(a.name)
# 28 多态示例
class Animal:
def say_who(self):
print('我是动物')
class Cat(Animal):
def say_who(self):
print('我是只猫')
class Human(Animal):
def say_who(self):
print('我是个人')
class Fish(Animal):
def say_who(self):
print("我是只鸟")
def commonUse(obj):
obj.say_who()
c = Cat()
h = Human()
f= Fish() #新增类和修改相应的调用即可
for item in(c,h):
commonUse(item)
#for item in (c,h,f): #新增调用
#commonUse(item)
#结果:
#我是猫咪
#我是人类
#我是只猫
#我是个人
#我是只鸟
# 29 异常捕获示例
def div(num):
try:
if num >100:
raise ValueError("Too big than 100")
elif not isinstance(num,int):
raise TypeError("Type error")
else:
return (100/num)
except ZeroDivisionError:
return "除数不能为0"
except TypeError:
return "必须是数值类型"
except ValueError:
return "值大于100了"
#finally:
#return 0
print(div(500))
#结果:值大于100了
#30 Python property及装饰器法实现getter/setter
class Color:
def __init__(self,rgb_value,name):
self._rgb_value=rgb_value
self._name = name
def _set_name(self,name):
if not name:
raise Exception ("Invalid value")
print(f"You are set color to name")
self._name = name
def _get_name(self):
print("You get color 0".format(self._name))
return self._name
def _del_name(self):
print(f"You are killing color self._name")
del self._name
name = property(_get_name,_set_name,_del_name,"Color's name property")
c = Color("#000F001","Bright Red")
c.name = "Red"
c.name
print([i for i in dir(c) if not i.startswith("__")])
del c.name
print([i for i in dir(c) if not i.startswith("__")])
c.name
class Color:
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name
@name.deleter
def name(self):
del self._name
c = Color()
c.name="Bright Red"
print(c.name)
#31 Python 用面向对象思维编写文件的解压、替换、压缩
import sys
import shutil
import zipfile
from pathlib import Path
class ZipReplace:
def __init__(self,filename,search_string,replace_string):
self.filename = filename
self.search_string= search_string
self.replace_string = replace_string
self.temp_dir = Path(f"temp-Path(filename).stem")
def zip_replace(self):
self.unzip()
self.replace_value()
self.zip()
def unzip(self):
self.temp_dir.mkdir()
with zipfile.ZipFile(self.filename,"r") as unzip:
unzip.extractall(self.temp_dir)
def replace_value(self):
for filename in self.temp_dir.iterdir():
with filename.open("r") as f:
contents= f.read()
contents = contents.replace(self.search_string,self.replace_string)
with filename.open("w") as f:
f.write(contents)
def zip(self):
with zipfile.ZipFile(self.filename,"w") as unzip:
for filename in self.temp_dir.iterdir():
unzip.write(filename,filename.name)
shutil.rmtree(self.temp_dir)
if __name__ == '__main__':
ZipReplace(*sys.argv[1:4]).zip_replace()
#V2 将解压和压缩环节定义为一个压缩类,文件处理(字符串替换)定义为一个类,文件处理继承自压缩类
#处理文本(字符串替换),处理图像(文件缩放),此时需要一个处理类,但是对文件的解压和压缩是通用步骤,所以可以定义在父类里
import sys
import zipfile
import shutil
from pathlib import Path
class ZipProcessor:
def __init__(self,zipname):
self.zipname = zipname
self.temp_dir = Path(f"temp-Path(zipname).stem")
def process_zip(self):
self.unzip()
self.process_files()
self.zip()
def unzip(self):
self.temp_dir.mkdir()
with zipfile.ZipFile(self.zipname,'r') as unzip:
unzip.extractall(self.temp_dir)
def zip(self):
with zipfile.ZipFile(self.zipname,'w') as zip:
for filename in self.temp_dir.iterdir():
zip.write(filename,filename.name)
shutil.rmtree(self.temp_dir)
class ZipReplace(ZipProcessor):
def __init__(self,filename,search_string,replace_string):
super().__init__(filename) #引用父类属性,需显式调用
self.search_string = search_string
self.replace_string = replace_string
def process_files(self):
for filename in self.temp_dir.iterdir():
with filename.open("r") as f:
contents= f.read()
contents = contents.replace(self.search_string,self.replace_string)
with filename.open("w") as f:
f.write(contents)
if __name__ == '__main__':
ZipReplace(*sys.argv[1:4]).process_zip()
#32 Python里函数的参数传递示例
def default_arg(x,y="y1",a,b="b1"): #SyntaxError: non-default argument follows default argument
print(x,y,a,b)
default_arg("x1","y2")
def default_args(x,a,y="y1",b="b1"):
print(x,a,y,b)
default_args("x1","y2") # x和a是必选参数
def default_args2(x,y="y1",*,a,b="b1"):
print(x,a,y,b)
#default_args2("x1") # TypeError: default_args2() missing 1 required keyword-only argument: 'a'
default_args2("x1",a="y2")
number = 5
def funky_function(number=number):
print(number)
number=6
funky_function(8)
funky_function() #函数定义了参数,但没传递时,如果函数里用到了该变量,则值为调用时的参数的值。
print(number)
以上是关于Python面向对象的30个小例子的主要内容,如果未能解决你的问题,请参考以下文章