李宁老师已经在「极客起源」 微信公众号推出《Python编程思想》电子书,囊括了Python的核心技术,以及Python的主要函数库的使用方法。读者可以在「极客起源」 公众号中输入 160442 开始学习。

《Python编程思想》总目录

《Python编程思想》专栏

目录

1. 类变量和实例变量

2. 使用 property函数定义属性


在类体内定义的变量,默认属于类本身。如果把类当成类命名空间,那么该类变量其实就是定义在类命名空间内的变量。

1. 类变量和实例变量

在类命名空间内定义的变量就属于类变量,Python可以使用类来读取、修改类变量。例如,下面代码定义了一个 Teacher类,并为该类定义了多个类变量。

示例代码:class_var.py

class Teacher :name = '李宁'salary = 66666.66post_code = '12345678'def print_info (self):# 尝试直接访问类变量
#        print(name) # 报错# 通过类来访问类变量print(Teacher.name) # 输出 广州print(Teacher.post_code) # 输出 510660
# 通过类来访问Address类的类变量
print(Teacher.name)
teacher = Teacher()
teacher.print_info()
# 修改Teacher类的类变量
Teacher.name = '王军'
Teacher.post_code = '87654321'
teacher.print_info()

在这段代码中为Teacher类定义了两个类变量。

对于类变量而言,它们就是属于在类命名空间内定义的变量,因此程序不能直接访问这些变量,程序必须使用类名来调用类变量。不管是在全局范围内还是函数内访问这些类变量,都必须使用类名进行访问。

当程序第1次调用 Teacher对象的print_info()方法输出两个类变量时,将会输出这两个类变量的初始值。接下来程序通过 Teacher类修改了两个类变量的值,因此当程序第2次通过print_info方法输出两个类变量时,将会输出这两个类变量修改之后的值。

运行上面代码,将会看到如下输出结果:

李宁
李宁
12345678
王军
87654321

实际上,Python完全允许使用对象来访问该对象所属类的类变量。看下面的程序:

示例代码:class_instance_access_classvar.py

class Country:# 定义两个类变量value1 = '中国'value2 = 960def print_info (self):print('info方法中: ', self.value1)print('info方法中: ', self.value2)country = Country()
print(country.value1) # 中国
print(country.value2) # 960
country.print_info()# 修改Country类的两个类变量
Country.value1 = '美国'
Country.value2 = 1234
# 调用print_info()方法
country.print_info()

这段代码的Country类中定义了两个类变量,接下来程序完全可以使用 Country对象来访问这两个类变量。

在这段代码的Country类的print_info方法中,程序使用self访问 Country类的类变量,此时self代表print_info方法的调用者,也就是 Country对象,因此这是合法的。

在主程序代码区,程序创建了 Country对象,并通过对象调用Country对象的value1和value2类变量,这也是合法的。

实际上,程序通过对象访问类变量,其本质还是通过类名在访问类变量。运行上面程序,将看到如下输出结果:

中国
960
info方法中:  中国
info方法中:  960
info方法中:  美国
info方法中:  1234

由于通过对象访问类变量的本质还是通过类名在访问,因此如果类变量发生了改变,当程序访问这些类变量时也会读到修改之后的值。例如为程序增加如下代码(接前面的代码),修改Country类的两个类变量。

Country.value1='韩国'
Country.value2 = 250
# 调用info()方法
country.print_info()

上面程序修改了Country类的两个类变量,然后通过对象调用print)info实例方法。运行上面代码,将看到如下输出结果。

info方法中:  韩国
info方法中:  250

从上面的输出结果可以看到,通过实例访问类变量的本质依然是通过类名在访问。需要说明的是,Python允许通过对象访问类变量,但如果程序通过对象尝试对类变量赋值,此时性质就变了。Python是动态语言,赋值语句往往意味着定义新变量。因此,如果程序通过对象对类变量赋值,其实不是对“类变量赋值”,而是定义新的实例变量。

看下面的代码:

实例代码:new_class_var.py

class Product:# 定义两个类变量name = 'iMac'price = 11000# 定义实例方法def buy(self, name, price):# 下面赋值语句不是对类变量赋值,而是定义新的实例变量self.name = nameself.price = price# 创建Product对象
product = Product()
product.buy('iPhone', 8000)
# 访问product的name和price实例变量
print(product.name) # iPhone
print(product.price) # 8000
# 访问Product的name和price类变量
print(Product.name) # iMac
print(Product.price) # 11000Product.name = '类变量name'
Product.price = '类变量price'
# 访问product的name和price实例变量
print(product.name)
print(product.price)product.name = '实例变量name'
product.price = '实例变量price'
print(Product.name)
print(Product.price)

在这段代码中通过实例对name和price变量赋值,看上去很像是对类变量赋值,但实际上不是,而是重新定义了两个实例变量(如果第1次调用该方法)。

在这段diamante中调用 Product对象的 buy()方法之后,访问 Product对象的name和price变量。由于该对象本身已有这两个实例变量,因此程序将会输出该对象的实例变量的值。接下来程序通过Product访问它的name和price类变量,此时才是真的访问类变量。

运行上面程序,将看到如下输出结果:

iPhone
8000
iMac
11000
iPhone
8000
类变量name
类变量price

如果程序通过类修改了两个类变量的值,程序中 Product的实例变量的值也不会受到任何影响。例如如下代码。

Product.name = '类变量name'
Product.price = '类变量price'
# 访问product的name和price实例变量
print(product.name)
print(product.price)

运行上面代码,可以看到如下输出结果

iPhone
8000

上面程序开始就修改了Product类中两个类变量的值,但这种修改对 Inventory对象的实例变量没有任何影响。同样,如果程序对一个对象的实例变量进行了修改,这种修改也不会影响类变量和其他对象的实例变量。例如如下代码。

product.name = '实例变量name'
product.price = '实例变量price'
print(Product.name)
print(Product.price)

运行上面代码,将会看到如下输出结果。

类变量name
类变量 price

从上面的输出结果来看,程序输出的依然是之前对类变量所赋的两个值。

2. 使用 property函数定义属性

如果为 Python类定义了getter和setter等访问器方法,可使用 property函数将它们定义成属性(相当于实例变量)。

property函数的语法格式如下:

property(fget=None, fset=None, fdel-None, doc=None)

从上面的语法格式可以看出,在使用 property函数时,可传入4个参数,分别代表 getter方法、 setter方法、del方法和doc,其中doc是一个文档字符串,用于说明该属性。当然,开发者调用 property也可传入0个(既不能读,也不能写的属性)、1个(只读属性)、2个(读写属性)、3个(读写属性,也可删除)和4个(读写属性,也可删除,包含文档说明)参数。

例如,如下程序定义了一个 Rectangle类,该类使用 property函数定义了一个size属性。

示例代码:rectangle.py

class Rectangle:# 定义构造方法def __init__(self, width, height):self.width = widthself.height = height# 定义set_size()函数def set_size (self , size):self.width, self.height = size# 定义getsize()函数def get_size (self):return self.width, self.height# 定义getsize()函数def del_size (self):self.width, self.height = 0, 0  # 使用property定义属性size = property(get_size, set_size, del_size, '用于描述矩形大小的属性')
# 访问size属性的说明文档
print(Rectangle.size.__doc__)
# 通过内置的help()函数查看Rectangle.size的说明文档
help(Rectangle.size)
rect = Rectangle(5, 6)
# 访问rect的size属性
print(rect.size) # (5, 6)
# 对rect的size属性赋值
rect.size = 10, 12
# 访问rect的width、height实例变量
print(rect.width) # 10
print(rect.height) # 12
# 删除rect的size属性
del rect.size
# 访问rect的width、height实例变量
print(rect.width) # 0
print(rect.height) # 0

这段代码使用 property函数定义了一个size属性,在定义该属性时一共传入了4个参数,这意味着该属性可读、可写、可删除,也有说明文档。所以,该程序尝试对Rectangle对象的size属性进行读、写、删除操作,其实这种读、写、删除操作分别被委托给 get_size()、 set_size()和 del_size()方法来实现。

运行上面程序,将会看到如下输出结果:

用于描述矩形大小的属性
Help on property:用于描述矩形大小的属性(5, 6)
10
12
0
0

在使用 property函数定义属性时,也可根据需要只传入少量的参数。例如,如下代码使用property函数定义了一个读写属性,该属性不能删除。

class Person :def __init__ (self, first, last):self.first = firstself.last = lastdef get_fullname(self):return self.first + ',' + self.lastdef set_fullname(self, fullname):first_last = fullname.rsplit(',');self.first = first_last[0]self.last = first_last[1]# 使用property()函数定义fullname属性,只传入2个参数# 该属性是一个读写属性,但不能删除fullname = property(get_fullname, set_fullname)
p = Person('子龙', '赵')
# 访问fullname属性
print(p.fullname)
# 对fullname属性赋值
p.fullname = '云长,关'
print(p.first)
print(p.last)

在这段代码中使用 property函数定义了 fullname属性,该程序使用 property()函数时只传入两个参数,分别作为 getter和 setter方法,因此该属性是一个读写属性,不能删除。

运行这段代码,将看到如下输出结果:

子龙,赵
云长
关

-----------------支持作者请转发本文,也可以加李宁老师微信:unitymarvel,或扫描下面二维码加微信--------

欢迎关注  极客起源  微信公众号,更多精彩视频和文章等着你哦!

Python编程思想(26):成员变量相关推荐

  1. Python编程思想(24):类的实例方法

    李宁老师已经在「极客起源」 微信公众号推出<Python编程思想>电子书,囊括了Python的核心技术,以及Python的主要函数库的使用方法.读者可以在「极客起源」 公众号中输入 160 ...

  2. Python编程思想【系列文章】

    <Python编程思想>专栏 本系列文章持续更新中....... 李宁老师已经在「极客起源」 微信公众号推出<Python编程思想>电子书,囊括了Python的核心技术,以及P ...

  3. Python编程思想(4):字符串类型

    <Python编程思想>总目录 目录 1. 字符串和转义符 2. 字符串内建函数 3. 字符串高级操作 4. 保持字符串的原汁原味 5. 长字符串 字符串的意思就是"一串字符&q ...

  4. Python编程思想(18):哇!原来Python参数还可以这样用

    李宁老师已经在「极客起源」 微信公众号推出<Python编程思想>电子书,囊括了Python的核心技术,以及Python的主要函数库的使用方法.读者可以在「极客起源」 公众号中输入 160 ...

  5. Python编程思想(8):使用字典

    <Python编程思想>总目录 目录 1. 创建字典 2. 字典的基本用法 3. 与字典相关的方法 字典是Python提供的一种常用的数据结构,可以用于保存具有映射关系的数据.比如有成绩单 ...

  6. Python编程思想(9):条件语句(if)

    <Python编程思想>总目录 上一篇:Python编程思想(8):使用字典 目录 1. if语句基础 2. 由于缩进错误引发的血案 3. if条件的类型 4. pass语句 if语句用于 ...

  7. Python编程思想(16):压缩与排序列表

    李宁老师已经在「极客起源」 微信公众号推出<Python编程思想>电子书,囊括了Python的核心技术,以及Python的主要函数库的使用方法.读者可以在「极客起源」 公众号中输入 160 ...

  8. 站长在线经典Python题:使用Python编程思想解决鸡兔同笼的问题的4种方法

    欢迎你来到站长在线的Python题库,鸡兔写完Python教程以后,还是来一个Python的题目吧!想来想去,还是写一个经典的题目为好,作为本栏目的第一个题目.我就想到了比较热门的题目<鸡兔同笼 ...

  9. python 私有和保护成员变量如何实现?—— 单下划线 开始的成员变量叫做保护变量,意思是只有类实例和子类实例能访问到这些变量; 双下划线 开始的是私有成员,意思是只有类对象自己能访问...

    默认情况下,Python中的成员函数和成员变量都是公开的(public),在python中没有类似public,private等关键词来修饰成员函数和成员变量. 在python中定义私有变量只需要在变 ...

最新文章

  1. java无参试题_JavaEE基础面试题0
  2. LeetCode 1723. 完成所有工作的最短时间(DFS+剪枝 / 状态压缩DP)
  3. DFS走迷宫问题(非最短路径)
  4. 【招聘内推】推荐策略产品经理-阿里文娱优酷产品直招
  5. 给力的网络 有道的性能——802.11n与WLAN
  6. 速达服务器远程登录设置,ERP速达软件online远程客户端登录常见问题(三)
  7. 解决拯救者Y7000打游戏,看视频没有声音的问题
  8. 《图算法》第五章 中心性算法-2
  9. android开发简历,轻松拿到了阿里Android高级开发工程师的offer
  10. 仿邓杰作品(艺家网站)总结
  11. 天池-小布助手对话短文本语义匹配 复赛rank3、决赛rank4代码及解决方案
  12. 基于python爬虫数据分析论文_基于Python的招聘网站信息爬取与数据分析
  13. 逆向破解之160个CrackMe —— 023-024
  14. Android加载预览PDF文件
  15. 安装python发生的报错
  16. SSH 官网下载地址
  17. html 修改表格行背景,HTML表格标记教程(20):行的背景色属性BGCOLOR
  18. 计算机科学与导论论文样例,计算机科学导论论文684413422
  19. 百度地图Polyline实现多颜色绘制
  20. Pascal VOC数据集 下载 百度云

热门文章

  1. (二) CPU 性能测试 (不同品牌CPU算力比较)
  2. 请问函数f(x)=sinh(x)的特性。
  3. 西电捷通:TISec系统的高可用性架构
  4. 打造数字丝绸之路 西安与云计算的不解之缘
  5. 中国大数据产业全景图谱(2022年) 附下载
  6. 电子统计台账:海量数据中导入特定行,极力减少键盘编辑工作量
  7. 输出大写字母字符串中每个大写字母之后的第5个字母所对应的小写字母
  8. win10安装autocad 2013出现command line option syntax error
  9. 【GIS数据网盘免费分享】含77个城市建筑轮廓矢量图、POI数据,OSM数据~持续更新,长期有效
  10. 通俗易懂地讲解《并查集》