用类存储数据

类实际上就是一个数据结构,对于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 = nameself.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 = nameself.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 = nameself.age = agedef set(self,job):self.job = jobreturn selfdef 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种:

  1. 返回设置后的值
  2. 返回设置前的值
  3. 返回对象自身
  4. 返回布尔值,表示是否设置成功

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

class Person:skin = "yellow"def __init__(self,name,age):self.name = nameself.age = agedef set(self,job):self.job = jobreturn selfdef 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.namedef get_age(self):return self.agedef get_job(self):return self.job

合并setter和getter

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

例如,对于job属性:

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

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

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

python的属性管理

上面解释了各种setter、getter的方式,还解释了将它们进行合并。

实际上在python中访问、设置、删除对象属性的时候,大概有以下几种方式:

  1. 使用内置函数getattr()、setattr()和delattr()
  2. 自己编写getter()setter()deleter()方法
  3. 重载__getattr__()__setattr__()__delattr__()运算符,这决定了x.y的访问、赋值方式以及del x.y的方式
  4. 使用__getattribute__()方法
  5. 使用描述符协议
  6. 使用property协议,它是一种特殊的描述符

这些还未介绍到的属性管理方式,在后面的文章中会逐渐展开解释。

总结

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

转载于:https://www.cnblogs.com/f-ck-need-u/p/10091181.html

Python面向对象基础:设置对象属性相关推荐

  1. Python面向对象基础:编码细节和注意事项

    在前面,我用了3篇文章解释python的面向对象: 面向对象:从代码复用开始 面向对象:设置对象属性 类和对象的名称空间 本篇是第4篇,用一个完整的示例来解释面向对象的一些细节. 例子的模型是父类Em ...

  2. Python面向对象基础示例_创建对象

    Python面向对象基础示例_创建对象 python是面向对象的语言,你可以很轻松的创建一个类和对象.本书代码源自<<Python 3 Object-Oriented Programmin ...

  3. Python面向对象基础(上)—Python Day7

    导入 --Python面向对象基础 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 面向对象 ...

  4. matplotlib之pyplot模块——获取/设置对象属性值(setp()、getp/get())

    当前有效matplotlib版本为:3.4.1. 概述 pyplot模块提供了获取/设置对象属性值的接口.功能类似于Python内置函数getattr和setattr.从源码上来看,get()是get ...

  5. 对象存储HTML自定义属性,设置对象属性_对象存储服务 OBS_SDK参考_Node.js_上传对象_华为云...

    开发过程中,您有任何问题可以在github上提交issue,或者在华为云对象存储服务论坛中发帖求助.接口参考文档详细介绍了每个接口的参数和使用方法. 您可以在上传对象时设置对象属性.对象属性包含对象长 ...

  6. 获取Python中的所有对象属性?

    本文翻译自:Get all object attributes in Python? Is there a way to get all attributes/methods/fields/etc. ...

  7. C#通过属性名字符串获取、设置对象属性值

    目录 #通过反射获取对象属性值并设置属性值 0.定义一个类 1.通过属性名(字符串)获取对象属性值 2.通过属性名(字符串)设置对象属性值 #获取对象的所有属性名称及类型 #判断对象是否包含某个属性 ...

  8. java 反射 设置属性_Java通过反射机制动态设置对象属性值的方法

    /** * MethodName: getReflection * Description:解析respXML 在通过反射设置对象属性值 * User: liqijing * Date:2015-7- ...

  9. 【MATLAB】基本绘图 ( 句柄值 | 对象句柄值获取 | 创建对象时获取句柄值 | 函数获取句柄值 | 获取 / 设置 对象属性 | 获取对象属性 )

    文章目录 一.对象句柄值获取 1.句柄值 2.创建对象时获取句柄值 3.函数获取句柄值 4.获取 / 设置 对象属性 二.获取对象属性 1.获取 线 对象属性 2.获取 坐标轴 对象属性 一.对象句柄 ...

最新文章

  1. LeetCode 11 Container With Most Water
  2. sublime插件开发教程(附源码)
  3. mysql组合索引的命中情况
  4. jsf表单验证_JSF:在正确的阶段进行验证(了解生命周期)
  5. xshell利用linux rz sz 命令上传、下载文件
  6. mysql 的hash和b tree_mysql索引hash索引和b-tree索引的区别
  7. 60、剑指offer--把二叉树打印成多行
  8. r语言 tunerf函数_R语言非参时间序列(六):波动脉冲响应(VIR)中的关键公式推导...
  9. J2ME Canvas切换闪屏问题解决
  10. 基于VRML的虚拟校园漫游系统
  11. php实现鼠标悬停显示下拉菜单,jquery实现鼠标滑过显示二级下拉菜单效果
  12. 博客中Java开发的软硬件环境
  13. vscode安装插件以及配置anaconda
  14. 嵌入式开发中,嵌入式硬件和软件有什么区别?
  15. 人脸识别——基于百度智能云实现
  16. Android MediaPalyer实现视频播放
  17. phobos勒索病毒的处理,警惕phobos卷土从来
  18. CCF(中国计算机学会)推荐的人工智能与模式识别领域国际期刊、会议列表x学术会议
  19. python对象的生命周期_(python)通过一个代码例子来分析对象的生命周期 | 学步园...
  20. uniapp 点击按钮跳转到当前应用的App Store中

热门文章

  1. iOS_根据文字字数动态确定Label宽高
  2. 【转】Traceview的使用
  3. C# 多态(接口、虚方法、抽象类)的理解
  4. 两边放动物对战守城的游戏_集合啦!动物森友会定制周边;百战天虫 大混战发布...
  5. python如何读取mat文件可视化_python Matplotlib数据可视化(1):简单入门
  6. 华为云交付项目服务器配置表,云端服务器配置表
  7. oracle+view性能,Oracle 10g的隐含参数_complex_view_merging引发的性能问题
  8. 用java编写运行的小游戏_第一次用Java编写小游戏!
  9. Halcon模板轮廓坐标点获取
  10. python redis处理高并发-Python高并发解决方案实现过程详解