Python 面向对象编程:方法重载、动态性与封装详解
本文详解Python面向对象编程特性。重点说明Python不支持传统方法重载,同名方法仅保留最后一个;演示如何动态为类添加或修改方法;解析私有属性与方法的双下划线命名规则及访问方式;介绍@property装饰器实现属性读写控制,并总结各类成员命名规范。
Python 面向对象
方法没有重载
在其他编程语言中,允许定义多个同名方法,只要方法签名唯一即可。方法签名由方法名、参数数量以及参数类型三个部分组成。
在 Python 中,方法参数无需声明类型(类型在调用时确定),且参数数量可通过可变参数灵活控制。因此,Python 不支持传统意义上的方法重载。定义一个方法即可通过不同方式调用,这等效于其他语言中的方法重载功能。
若在类体中定义多个同名方法,仅有最后一个定义的方法生效。
建议:避免使用重名方法,因为 Python 中方法不存在重载机制。
#Python 中没有方法的重载。定义多个同名方法,只有最后一个有效
class Person:
def say_hi(self):
print("hello")
def say_hi(self,name):
print("{0},hello".format(name))
p1 = Person()
#p1.say_hi() #不带参,报错:TypeError: say_hi() missing 1 required positional argument: 'name'
p1.say_hi("陈浩")
方法的动态性
Python 属于动态语言,支持在运行时动态为类添加新方法,或动态修改类中已存在的方法。
#测试方法的动态性
class Person:
def work(self):
print("努力上班!")
def play_game(self):
print("玩游戏")
def work2(self):
print("好好工作,努力上班!")
Person.play = play_game
Person.work = work2
p = Person()
p.play() # 玩游戏
p.work() # 好好工作,努力上班!
示例显示,Person 类动态新增了 play_game 方法,并使用 work2 替换了原有的 work 方法。
私有属性和私有方法(实现封装)
Python 对类的成员访问控制没有严格限制,这与其他面向对象语言存在区别。关于私有属性和私有方法,需注意以下要点:
- 通常约定,以两个下划线("__")开头的属性为私有(private),其余为公共(public)。
- 类内部可以访问私有属性或私有方法。
- 类外部不能直接访问私有属性或私有方法。
- 类外部可通过“_类名__私有属性(方法)名”的特殊语法访问私有属性或私有方法。
【注】方法本质上也是属性,区别仅在于可通过()执行。因此,上述私有属性和公有属性的规则同样适用于私有方法和公有方法。以下测试中同时包含了私有方法和公有方法的示例。
【测试】私有属性和公有属性使用测试
#测试私有属性、私有方法
class Employee:
__company = "Danone" #私有类属性. 通过 dir 可以查到_Employee__company
def __init__(self, name, age):
self.name = name
self.__age = age #私有实例属性
def say_company(self):
print("我的公司是:",Employee.__company) #类内部可以直接访问私有属性
print(self.name,"的年龄是:",self.__age)
def __work(self): #私有实例方法 通过 dir 可以查到_Employee__work
return "工作!好好工作,好好赚钱,娶个媳妇!"
p1 = Employee("陈浩",18)
print(p1.name)
# 陈浩
print(dir(p1))
# ['_Employee__age', '_Employee__company', '_Employee__work', '__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__', 'name', 'say_company']
p1.say_company()
# 我的公司是: Danone
# 陈浩 的年龄是: 18
print(p1._Employee__age) #通过这种方式可以直接访问到私有属性 。通过 dir 可以查到属性:_Employee__age
# 18
print(p1._Employee__work())
# 工作!好好工作,好好赚钱,娶个媳妇!
#print(p1.__age) #直接访问私有属性,报错
#print(p1.__work()) #直接访问私有方法,报错
@property 装饰器
@property 装饰器可将方法的调用方式转换为“属性调用”。
class Employee:
def __init__(self, name, salary):
self.name = name
self.__salary = salary
@property #getter方法
def salary(self):
return self.__salary
@salary.setter #setter方法
def salary(self, salary):
self.__salary = salary
@salary.deleter #deleter方法
def salary(self):
self.__salary = 0
emp = Employee("陈浩", 6000)
print("{0}当前的薪资是{1}".format(emp.name,emp.salary))
# 陈浩当前的薪资是6000
print("*"*12, "加薪啦", "*"*12)
emp.salary = 10000
print("{0}当前的薪资是{1}".format(emp.name,emp.salary))
# 陈浩当前的薪资是10000
print("*"*12, "离职了", "*"*12)
del emp.salary
print("{0}当前的薪资是{1}".format(emp.name,emp.salary))
# 陈浩当前的薪资是0
@property 主要用于辅助处理属性的读操作和写操作。对于某一属性,可直接通过类名.方法名 = 值进行赋值操作。
属性和方法命名总结
- _xxx:保护成员,无法通过“from module import *”导入,仅类对象和子类对象可访问这些成员。
- __xxx__:系统定义的特殊成员。
- __xxx:类中的私有成员,仅类对象自身可访问,子类对象亦不可访问(但在类外部可通过“对象名. _类名__xxx”这种特殊方式访问。Python 不存在严格意义上的私有成员)。
注:再次强调,方法和属性均遵循上述命名规则。
到此这篇关于Python 面向对象编程详解 的文章就介绍到这了,更多相关Python 面向对象 内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









