python面向对象编程二

xiaoxiao2025-03-07  13

三、属性和方法

类由成员变量(对应于对象的属性)和成员函数(对应于对象的方法)组成。属性是对数据的封装,方法则表示对象具有的行为。

Python的构造函数、析构函数、私有属性或方法都是通过名称约定区分的。

此外,Python还提供了一些有用的内置方法,简化了类的实现

1、类的成员属性

Python的类的成员一般分为私有属性和公有属性,像C++有定义属性的关键字(publicprivateprotect),而Python没有这类关键字,默认情况下所有的属性都是“公有的”,对公有属性的访问没有任何限制,且都会被子类继承,也能从子类中进行访问。

若不希望类中的成员在类外被直接访问,就要定义为私有属性。Python使用约定属性名称来划分属性类型。若属性的名字以两个下划线开始,表示私有属性;反之,没有使用双下划线开始的表示公有属性。类的成员变量及成员函数都同样使用这个约定。

另外,Python没有保护类型的修饰符。

Python的实例变量变量:

实例变量是以self为前缀的成员变量,没有该前缀的成员变量是普通的局部变量。

C++中有一类特殊的属性称为静态变量。静态变量能被实例化对象调用,还可以被类直接调用。当创建新的实例化对象后,静态变量并不会获取新的内存空间,而是使用类创建的内存空间。因此,静态变量能够被多个实例化对象共享。

Python中静态变量称为类变量,类变量可以在该类的所有实例中被共享。

 

关于Python私有属性的访问:

 

类的外部不能直接访问私有属性。

Python提供了直接访问私有属性的方式,可用于程序的测试和调试。

私有属性访问的格式:

   instance._classname__attribute

说明:

instance表示实例化对象;

classname表示类名;

attibute表示私有属性

注意:classname之前是单下划线,attribute之前是双下划线

class Fruit: def __init__(self,color): self.__color=color #定义私有变量; if __name__=="__main__": apple=Fruit('red') #创建实例对象 print(apple._Fruit__color) #调用类的私有变量;

输出结果:red

 

# -*- coding: utf-8 -*- """ Spyder Editor This is a temporary script file. """ class Fruit(object): price=0 #定义类类变量 def __init__(self,color): self.__color=color #定义私有变量; def getColor(self): print(self.__color) #输出私有变量 @staticmethod #使用@staticmethod修饰器定义静态方法 def getPrice(): print(Fruit.price) def __getPrice(): #定义私有方法 Fruit.price=Fruit.price+10 print(Fruit.price) count=staticmethod(__getPrice) #使用staticmethod 方法定义静态方法 if __name__=="__main__": apple=Fruit('red') #创建实例对象 apple.getPrice() #使用实例调用方法 Fruit.count() #使用类名调用静态方法 banana=Fruit('yellow') Fruit.getPrice() Fruit.count()

 输出方法:

0 10 10 20

#构造函数应用一 class Person(object): def __init__(self,name='',age=0): self.name=name self.age=age def __str__(self): return "Person('%s','%d')" % (self.name,self.age) if __name__=="__main__": p=Person('Jack',25) print(p) p=Person() #可以创建空对象 print(p)

输出结果为:

Person('Jack','25') Person('','0')

 

#构造函数应用二 class Fruit(object): def __init__(self,color): self.__color=color def getColor(self): print(self.__color) def setColor(self,color): if color in ('red','black','white','gray','blue'): self.__color=color if __name__=="__main__": color='red' fruit=Fruit(color) fruit.getColor() fruit.setColor('blue') fruit.getColor() fruit.setColor('yellow') fruit.getColor() fruit.setColor('white') fruit.getColor()

输出结果:

red blue blue white 

类常用的内置方法

 

#析构函数应用 class Fruit(object): def __init__(self,color): #构造函数 self.__color=color #初始化属性color print(self.__color) def __del__(self): #析构函数 self.__color='' print('free...') def grow(self): print('grow...') if __name__=="__main__": color='red' fruit=Fruit(color) fruit.grow() del fruit #显示调用析构函数,不然无法保证析构函数何时被运行

输出结果:

red grow... free...

内置方法

描述

__init__(self, …)

初始化对象,在创建对象时调用

__del__(self)

释放对象,在对象被删除时调用

__str__(self)

生成对象的字符串表示,在使用print语句时被调用

__repr__(self)

生成对象的官方表示,在使用print语句时被调用

__getitem__(self, key)

获取序列的所有key对应的值,等价于seq[key]

__len__(self)

在调用内联函数len()时被调用

__cmp__(src, dst)

比较两个对象srcdst

 

 

 

内置方法

描述

__getattr__(self, name)

获取属性的值

__getattribute__(self, name)

获取属性的值,能更好地控制

 

__setattr__(self, name, val)

设置属性的值

__delattr__(self,name)

删除name属性

__call__(self, *args)

将实例对象作为函数调用

__gt__(self, other)

判断self对象是否大于other对象

__lt__(self, other)

判断self对象是否小于other对象

__ge__(self, other)

判断self对象是否大于或等于other对象

__le__(self, other)

判断self对象是否小于或等于other对象

__eq__(self, other)

判断self对象是否等于other对象

1__getatrr__()__setattr__()__getattribute__() 

当读取对象的某个属性时,Python会自动调用__getattr__()方法。例如,fruit.color将转换为fruit.__getattr__(color)

当使用赋值表达式对属性进行设置时,Python会自动调用__setattr__()方法。

__getattribute__()的功能与__getattr__()类似,用于获取属性的值,但__getattribute__()能提供更好的控制,使代码更健壮。

 

垃圾回收机制

Python使用垃圾回收机制来清理不再使用的对象。Python提供gc模块释放不再使用的对象,Python采用“引用计数”的算法来处理回收,即:当某个对象在其作用域内不再被其他对象引用时,Python就自动清除该对象。

Python的函数collect()可以一次性收集所有待处理的对象(gc.collect()

# -*- coding: utf-8 -*- """ Spyder Editor This is a temporary script file. """ #使用gc模块显示地调用垃圾回收器 import gc class Fruit(object):#定义水果类 def __init__ (self,name,color): #初始化 name,color 属性 self.__name=name self.__color=color def getColor(self): return self.__color #返回color def setColor(self,color): #定义color self.__color=color def getName(self): #返回name return self.__name def setName(self,color): self.__name=name #定义name class FruitShop(object): #定义水果店类 def __init__(self): self.fruits=[] def addFruit(self,fruit): #添加水果 fruit.parent=self #将Fruit类关联到FruitShop 类 self.fruits.append(fruit) if __name__=="__main__": shop=FruitShop() shop.addFruit(Fruit('apple','red')) shop.addFruit(Fruit('banana','yellow')) print(gc.get_referrers(shop)) #打印出与shop对象相关联的所有对象 print() del shop #删除shop 对象,但与其相关联的其他对象并未释放 print(gc.collect()) #显示地调用垃圾回收器,释放与shop对象关联的其他对象

 

#获取和设置对象的属性 class Fruit(object): def __init__(self,color='red',price=0): self.__color=color self.__price=price def __getatttibute__(self,name): #获取属性的方法 return object.__getattribute__(self,name) def __setattr__(self,name,value): #设置属性的方法 self.__dict__[name]=value # __dict__字典是类的内置属性,用于记录类定义的属性 #字典中的key表示属性名,value表示属性的值 if __name__=="__main__": fruit=Fruit("blue",10) print(fruit.__dict__.get('_Fruit__color')) #获取color属性值,因为color是私有 属性 print(fruit.__dict__.get('_Fruit__price')) #所以字典的索引表示为“_Fruit__color” fruit.__dict__['_Fruit__price']=5 #使用__dict__进行赋值 fruit.__dict__['_Fruit__color']='red' print(fruit.__dict__.get("_Fruit__color")) #h获取color属性的值 print(fruit.__dict__.get("_Fruit__price")) #获取price属性的值 print(fruit.__getattribute__('_Fruit__color')) print(fruit.__getattribute__('_Fruit__price'))

输出结果:

blue 10 red 5 red 5

去掉上例__getattribute__() __setattr__()的实现代码,并不会影响输出结果,但这些方法可以实现对属性的控制,根据属性名做不同的处理。

如果类中将某个属性定义为序列,可以使用__getitem__()输出序列属性中的各个元素。

#获取对象的属性为序列中的各个元素 class FruitShop(object): def __getitem__(self,i): #获取水果店的水果 return self.fruits[i] if __name__=="__main__": shop=FruitShop() shop.fruits=['apple ', 'banana'] #给fruits 赋值 print(shop[1]) for item in shop: print(item,end='')

输出结果:

banana apple banana

 

__str__()用于生成对象的字符串表示。实现了该方法后,可以直接使用print语句输出对象,也可以通过函数str()触发其执行。

 

方法的动态特性:

Python作为动态脚本语言,编写的程序具有很强的动态性。

可以动态添加类的方法,将某个已经定义的函数添加到类中。添加新方法的语法格式为:

    class_name.method_name=function_name

其中,class_name表示类名,method_name表示新的方法名,function_name表示1个已经存在的函数。

还可以对已经定义的方法进行修改。修改方法的语法格式为:

    class_name.method_name=function_name

其中,class_name表示类名,method_name表示已经存在的方法名,function_name表示1个已经存在的函数,该赋值表达式表示将函数的内容更新到方法。

#动态添加方法 class Fruit(object): pass def add(self): #定义在类外的函数 print('grow...') if __name__=="__main__": Fruit.grow=add #d动态add添加函数 fruit=Fruit() fruit.grow()

输出结果:

grow...

#动态更新方法 class Fruit(object): def grow(self): print('grow...') def update(): #定义在类外的函数 print('grow......') if __name__=="__main__": fruit=Fruit() fruit.grow() fruit.grow=update #将grow方法更新为update() fruit.grow()

输出结果:

grow... grow......

例题

创建一个新类表示整数集合

初始时集合为空

每个特定的整数只能在集合中出现一次(注:必须在方法中强制实现)

内部数据表示

用一个列表存储集合中的元素

接口

insert(e):若整数e不存在,则插入e到集合中

member(e):若整数e在集合中返回True,否则返回False

remove(e):从集合中删除整数e,若不存在则出错

 

#动态更新方法 class intSet(object): """An intSet is a set of integers The value is represented by a list of ints,self.vals. Each int in the set occurs in self.vals exactly once.""" def __init__(self): """Create an empty set of inntergers""" self.vals=[] def insert(self,e): """Assumes e is an integer and inserts e into self""" if not e in self.vals: self.vals.append(e) def member(self,e): """Assumes e is an interger Returns True if e is in self,and False otherwise""" return e in self.vals def remove(self,e): """Assumes e is an integer and removes e from self Raises ValueError if e is not in self """ try: self.vals.remove(e) except: raise ValueError(str(e)+'not found') def __str__(self): """Returns a string representation of self""" self.vals.sort() return '{' +','.join([str(e) for e in self.vals ])+'}'

输出结果:

 

创建一个关于人的信息的类及相关方法(例题)

Personnamebirthday

Get last name

Sort by last name

Get age

import datetime class Person(object): def __init__(self,name): self.name=name self.birthday=None self.lastName=name.split(' ')[-1] def getLastName(self): return self.lastName def setBirthday(self,month,day,year): self.birthday=datetime.date(year,month,day) def getAge(self): if self.birthday==None: raise ValueError return ((datetime.date.today()-self.birthday).days)//365 def __lt__(self,other): if self.lastName==other.lastName: return self.name<other.name return self.lastName<other.lastName def __str__(self): return self.name p1=Person('William Eric Grimson') print(p1) print(p1.getLastName()) p1.setBirthday(1,2,1991) print(p1.getAge()) print() p2=Person('cher') print(p2.getLastName()) print() plist=[p1,p2] plist.sort() for p in plist: print(p)

输出结果:

William Eric Grimson Grimson 27

cher

William Eric Grimson cher


 

 

 

 

转载请注明原文地址: https://www.6miu.com/read-5025707.html

最新回复(0)