Python面向对象基础入门之设置对象属性


Posted in Python onDecember 11, 2018

前言

前面我们已经介绍了 python面向对象入门教程之从代码复用开始(一) ,这篇文章主要介绍的是关于Python面向对象之设置对象属性的相关内容,下面话不多说了,来一起看看详细的介绍吧

用类存储数据

类实际上就是一个数据结构,对于python而言,它是一个类似于字典的结构。当根据类创建了对象之后,这个对象就有了一个数据结构,包含一些赋值了的属性。在这一点上,它和其它语言的struct的作用是类似的:存储数据并提供数据检索功能

例如,下面是史上最简单的类:

class Person: pass

pass关键字表示这个类没有实际的逻辑体。这里只是定义了一个类,这个类的对象初始化时不会存放任何数据。现在,构造一个对象,让它和dict一样存放一些数据:

p = Person() # 构造对象
p.name = "longshuai" # 创建对象的属性name
p.age = 23   # 创建对象的属性age

现在,Person的实例对象p中就存放了两个属性:p.name和p.age。可以直接去检索存放在p中的数据:

print(p.name) # 输出"longshuai"
print(p.age) # 输出23

也可以使用dict来存储这些数据:

>>> d={}
>>> d["name"]="longshuai"
>>> d["age"]=23

>>> print(d["name"])
longshuai
>>> print(d["age"])
23

在数据存储方面,它们的作用是完全等价的。实际上对象/类在内部就是使用一个名为__dict__的dict类型来存放它所拥有的数据的。

>>> p.__dict__
{'name': 'longshuai', 'age': 23}

__init__()构造对象初始数据

上面的name和age属性是在构建了对象之后附加上去的,如果想要创建对象时就存放好数据,可以定义类的构造函数__init__()。例如:

class Person:
 def __init__(self,name,age):
  self.name = name
  self.age = age

然后创建对象的时候,传递name参数和age参数即可。

>>> p = Person("longshuai",23)
>>> p.__dict__
{'name': 'longshuai', 'age': 23}

如果想定义这个类公有的数据,可以将公有属性定义为类的属性。比如中国人都是黄皮肤:

class Person:
 skin = "yellow"
 def __init__(self,name,age):
  self.name = name
  self.age = age

这样每次创建Person的对象实例时,每个对象都会有相同的肤色:yellow。但注意,这个skin属性是类属性,不是对象属性,它是存放在类的名称空间中的。当对象真的需要这个属性的时候,会临时去检索类的名称空间来获取。看下面的__dict__字典即可知道:

>>> p = Person("longshuai",23)
>>> p.__dict__
{'name': 'longshuai', 'age': 23}
>>> p.skin
'yellow'

但注意,按照面向对象的封装原则,在类中定义类变量属性是不合理的,因为要在外部访问它需要通过x.y的方式,这意味着打开了封装好的"黑匣子",暴露了属性。除非真的有需要,否则可以将类变量的定义放进构造函数__init__()中,这样每个初始化的对象都会有该属性。

setter和getter方法

在面向对象的角度上考虑,一般是不建议直接在类的外部通过x.name的方式赋值、取值的。而是定义对应的方法,通过方法来取得对应的值。这两类方法称为setter、getter方法:setter用于赋值或设置属性值,getter用于取得属性值。

class Person:
 skin = "yellow"
 def __init__(self,name,age):
  self.name = name
  self.age = age
 def set(self,job):
  self.job = job
  return self
 def get(self):
  return self.name,self.age,self.job

上面的set方法用于设置一个新属性job。get用于返回对象的3个属性。

>>> p = Person("longshuai",23)
>>> p.set("manager")
>>> name, age, job = p.get()
>>> print([name,age,job])
['longshuai', 23, 'manager']

需要注意,setter方法可以有多种类型的返回值,常用的有4种:

  • 返回设置后的值
  • 返回设置前的值
  • 返回对象自身
  • 返回布尔值,表示是否设置成功

这4种返回值都很常见,特别是第三种用来串联对象方法的时候非常好用。修改上面的set方法:

class Person:
 skin = "yellow"
 def __init__(self,name,age):
  self.name = name
  self.age = age
 def set(self,job):
  self.job = job
  return self
 def get(self):
  return self.name,self.age,self.job

上面的set()返回self对象自身。于是串联set()和get():

>>> p = Person("longshuai",23)
>>> name,age,job = p.set("manager").get()

无论使用何种返回值方式,都不会真正影响程序的使用。但使用合理的返回值类型,可能会简化代码的编写。另外,决定了返回值的方式后,就不要再去修改,因为很可能会牵一发而动全身。

上面的getter返回了多个值,但一般来说getter只返回一个对应的属性。比如getname()返回name属性,getage()返回age属性等。这样需要定义多个getter方法。

def get_name(self):
 return self.name

def get_age(self):
 return self.age

def get_job(self):
 return self.job

合并setter和getter

很多时候可以合并setter和getter方法。合并的方式是判断方法的参数,如果调用方法的时候给了参数,就表示setter,没有给定参数,就表示是getter。

例如,对于job属性:

def set_get_job(self, job=None):
 if job:
  self.job = job
 else:
  return self.job

现在可以以给参数和不给参数两种不同的方式来调用set_get_job()方法:

p = Person("longshuai", 23)
p.set_get_job("manager")  # 给了参数,说明是setter
job = p.set_get_job()  # 没给参数,说明是getter

总结

本文介绍了各种设置对象属性的方式,属性其实就是数据,对象/类就是属性的容器,这一点很重要。我最开始学java的面向对象时,虽然对类和对象有那些教科书式的理解,但始终没有感受到类/对象其实就是一种用来存储数据的数据结构。直到学习了Python/Perl,我才意识到这一点,然后理解面向对象就容易的多了。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python实现代码行数统计示例分享
Feb 10 Python
一个计算身份证号码校验位的Python小程序
Aug 15 Python
在Python中用has_key()方法查找键是否存在的教程
May 21 Python
Python模块搜索概念介绍及模块安装方法介绍
Jun 03 Python
python matplotlib绘图,修改坐标轴刻度为文字的实例
May 25 Python
利用Python如何批量更新服务器文件
Jul 29 Python
对python中的 os.mkdir和os.mkdirs详解
Oct 16 Python
python构建基础的爬虫教学
Dec 23 Python
Python如何应用cx_Oracle获取oracle中的clob字段问题
Aug 27 Python
Tensorflow实现部分参数梯度更新操作
Jan 23 Python
Python logging模块原理解析及应用
Aug 13 Python
python制作微博图片爬取工具
Jan 16 Python
python提取包含关键字的整行数据方法
Dec 11 #Python
django开发post接口简单案例,获取参数值的方法
Dec 11 #Python
python面向对象入门教程之从代码复用开始(一)
Dec 11 #Python
python 运用Django 开发后台接口的实例
Dec 11 #Python
IntelliJ IDEA安装运行python插件方法
Dec 10 #Python
Python文件如何引入?详解引入Python文件步骤
Dec 10 #Python
python的继承知识点总结
Dec 10 #Python
You might like
使用apache模块rewrite_module (转)
2007/02/14 PHP
discuz安全提问算法
2007/06/06 PHP
php中防止SQL注入的最佳解决方法
2013/04/25 PHP
PHP处理SQL脚本文件导入到MySQL的代码实例
2014/03/17 PHP
Yii编程开发常见调用技巧集锦
2016/07/15 PHP
PHP实现求连续子数组最大和问题2种解决方法
2017/12/26 PHP
Jquery 获得服务器控件值的方法小结
2010/05/11 Javascript
javascript中获取下个月一号,是星期几
2012/06/01 Javascript
js实现全国省份城市级联下拉菜单效果代码
2015/09/07 Javascript
JavaScript使用DeviceOne开发实战(二) 生成调试安装包
2015/12/01 Javascript
Bootstrap开发实战之响应式轮播图
2016/06/02 Javascript
学习Angularjs分页指令
2016/07/01 Javascript
jquery插件autocomplete用法示例
2016/07/01 Javascript
jQuery的图片轮播插件PgwSlideshow使用详解
2016/08/11 Javascript
bootstrap下拉菜单使用方法解析
2017/01/13 Javascript
js获取当前页的URL与window.location.href简单方法
2017/02/13 Javascript
jQuery插件zTree实现获取当前选中节点在同级节点中序号的方法
2017/03/08 Javascript
vue.js移动数组位置,同时更新视图的方法
2018/03/08 Javascript
ES6 中可以提升幸福度的小功能
2018/08/06 Javascript
webpack的pitching loader详解
2019/09/23 Javascript
JS自定义对象创建与简单使用方法示例
2020/01/15 Javascript
[44:41]Fnatic vs Liquid 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
[00:15]TI9观赛名额抽取
2019/07/10 DOTA
详解python并发获取snmp信息及性能测试
2017/03/27 Python
python解析多层json操作示例
2019/12/30 Python
python GUI库图形界面开发之PyQt5信号与槽的高级使用技巧装饰器信号与槽详细使用方法与实例
2020/03/06 Python
Python PyQt5模块实现窗口GUI界面代码实例
2020/05/12 Python
canvas线条的属性详解
2018/03/27 HTML / CSS
Old Navy加拿大官网:美式休闲服饰品牌
2017/09/26 全球购物
毕业生应聘幼儿园的自荐信
2013/11/20 职场文书
感恩母亲节活动方案
2014/03/04 职场文书
元宵晚会主持词
2014/03/25 职场文书
继续教育心得体会(共6篇)
2016/01/19 职场文书
SQL优化老出错,那是你没弄明白MySQL解释计划用法
2021/11/27 MySQL
解决persistence.xml配置文件修改存放路径的问题
2022/02/24 Java/Android
为什么MySQL不建议使用SELECT *
2022/04/03 MySQL