Python3的构造函数和访问控制 - vip共享吧
  • 网站首页
  • IT技术笔记
    • Java教程
    • MySql数据库
    • PHP开发
    • Python教程
    • JavaScript
    • SEO优化
    • 常用工具
  • 好资源福利
    • 会员账号共享
  • 网站模板源码
    • 小程序源码
    • 网站源码
  • 共享网络资源
  • 更多功能
    • 留言吐槽
    • 文章归档
    • 我的邻居
    • 史上今日
    • 视频解析
    • 高清壁纸
    • 公告动态
    • 广告合作
    • 关于我们


导航菜单
  • 网站首页
  • IT技术笔记
    • Java教程
    • MySql数据库
    • PHP开发
    • Python教程
    • JavaScript
    • SEO优化
    • 常用工具
  • 好资源福利
    • 会员账号共享
  • 网站模板源码
    • 小程序源码
    • 网站源码
  • 共享网络资源
  • 更多功能
    • 留言吐槽
    • 文章归档
    • 我的邻居
    • 史上今日
    • 视频解析
    • 高清壁纸
    • 公告动态
    • 广告合作
    • 关于我们
Python

Python3的构造函数和访问控制

2024/9/6 韩俊  Python教程 883 0

在面向对象编程中,构造函数和访问控制是我们经常用到的,并且是面向对象很重要的特性。

构造函数

虽然我们需要类的所有实例拥有共同的属性, 但是我们不想让他们拥有共同的属性值,在对象创建后,我们可以调用一个函数来修改这些属性值。

class Human():
    def initdata(self, myname, myage):
        self.name = myname
        self.age = myage

    def speak(self):
        print("大家好,我是%s;我的年龄是%s" % (self.name, self.age))

luren_a = Human()
luren_a.initdata("ruhua", 18)
luren_a.speak()

luren_b = Human()
luren_b.initdata("zhaoritian", 17)
luren_b.speak()

我们发现上面那种方法重复繁琐,Python 语言可以通过定义一个名称为 __init__ 的函数,该函数叫做构造函数,在我们创建对象的时候,Python 解释器会自动调用构造函数。构造函数也是类的成员函数,至少也要拥有一个参数,我们知道第一个参数是用来接收调用对象本身的,在构造函数内部,我们可以把各种属性绑定到该参数上。

class Human():
    def __init__(self, myname, myage):
        self.name = myname
        self.age = myage

    def speak(self):
        print("大家好,我是%s;我的年龄是%s" % (self.name, self.age))

luren_a = Human("ruhua", 18)     # Python 解释器会自动调用构造函数,并把 luren_a 作为第一个实参传给构造函数
luren_a.speak()

luren_b = Human("xingxing", 17)  # Python 解释器会自动调用构造函数,并把 luren_b 作为第一个实参传给构造函数
luren_b.speak()

由于在构造函数中我们把调用构造函数的对象本身传过去,然后通过这个对象初始化属性,这样一来,可以实现每个对象拥有不同的属性值。

class Human():
    def __init__(self, myname):
        self.name = myname

luren_a = Human("ruhua")
luren_b = Human("xingxing")

print(luren_a.name)  # luren_a 对象的 name
print(luren_b.name)  # luren_b 对象的 name

假如我们定义一个圆类,对于所有的圆类产生的对象都有 π 这个属性,并且该属性对所有圆对象的值都是一样的, 我们没必要把 π 这个属性在每个对象创建的时候在构造函数内重新赋值,因为他们是一样的,我们可以把该属性定义在构造函数外面,我们称为该属性是属于类的(也就是所有对象共有一个)。

class Circle():
    PI = 3.1415926
    def __init__(self, radius):
        self.radius = radius

    def showarea(self):
        print(self.radius * self.PI)

redcircle = Circle(3)
redcircle.showarea()    # 用的是类的属性 PI

bluecircle = Circle(5)  # 用的是类的属性 PI
bluecircle.showarea()

Circle.PI = 1           # 可以通过类改变属性 PI
print(redcircle.PI)     # 用的是类的属性 PI
print(bluecircle.PI)    # 用的是类的属性 PI

Python 如何实现让所有对象共享一个属性的呢?很简单,当 Python 发现类内存在属于类的属性时,只需要在每个对象初始化时,让对象中同名属性指向类属性即可。 因此,我们试图通过某个对象修改属于类的属性,则对其它对象不起作用,因为修改的只是这个对象属性本身的指向,所有的其它对象属性还在指向这个属于类的属性。

class Circle():
    PI = 3.1415926
    def __init__(self, radius):
        self.radius = radius

redcircle = Circle(3)
bluecircle = Circle(5)
redcircle.PI = 1      # 只是改变了 redcircle 对象的属性 PI 指向

print(redcircle.PI)   # 1
print(bluecircle.PI)  # bluecircle 对象的属性 PI 还在指向 Cirle 类的属性 PI
print(Circle.PI)      # Circle 类的属性 PI 只能通过 Cirle 类来改变

访问控制

我们在进行面向对象编程时,最好不要直接通过对象来访问(读或写)属性,而是通过类提供的函数进行读写属性操作,要养成良好的编程习惯。

class Human():
    def __init__(self, myname):
        self.name = myname

    def getname(self):
        return self.name

    def setname(self, newname):
        self.name = newname

luren_a = Human("ruhua")
print(luren_a.getname())        # 访问属性
luren_a.setname("wanghuahua")   # 修改属性
print(luren_a.getname())

人的天性都是非自觉的,程序员也是人,所以需要约束,我们刚刚讲过最好不要通过实例直接访问类的属性, 那只是要求程序员自觉遵守,所以我们可以强制性约束,为了让内部属性不被外部访问, 我们可以在属性的名称前加上两个下划线 __,在 Python 中,实例的变量名如果以 __ 开头,就变成了一个私有变量(private),私有变量只有在类的内部可以访问(读写),在类的外部不能访问(读写)。

class Human():
    def __init__(self, myname):
        self.__name = myname

    def getname(self):
        return self.__name      # 类的内部可以访问

    def setname(self, newname):
        self.__name = newname   # 类的内部可以访问

luren_a = Human("ruhua")
print(luren_a.getname())
luren_a.setname("wanghuahua")
print(luren_a.getname())

print(luren_a.__name)          # 报异常,因为类的外部无法访问
luren_a.__name = "wanghuahua"  # 报异常,因为类的外部无法访问

有时候,我们会遇到以单下划线开头的变量,这样的实例变量在外部是可以访问的,我们最好不要去访问,这是一个不成文的约定。

class Human():
    def __init__(self, myname):
        self._name = myname

luren_a = Human("ruhua")
print(luren_a._name)  # 类的外部可以访问 _name,但最好不要访问,要遵守约定

Python 本身不进行访问控制的语法检查,以双下划线开头的变量不能访问的原因, 仅仅是因为 Python 在类内部把所有以 __ 开头的变量进行了更名,我们如果知道更改后的属性名,就可以在外部进行访问该属性,注意不同版本的 Python 解释器可能会把该变量改成不同的变量名。

class Human():
    def __init__(self, myname):
        self.__name = myname

luren_a = Human("ruhua")
print(luren_a._Human__name)    # Python 3.7 版本把名字改成了 _Human__name
Human.__name = "wanghuahua"
print(luren_a.__name)          # Python 只对类内部 __开头的变量做改名,所以可以访问

# 我们可以通过 id 函数知道它们并不是一个变量
print(id(luren_a.__name))
print(id(luren_a._Human__name))

本节重要知识点

构造函数如何定义

Python 实现访问控制的方法

点赞:0 分享

上一篇
Python3继承和多态的理解
下一篇
python3类和对象的概念
作者头像 作者名称 作者性别
韩俊

热门推荐

1 python动态绑定属性和方法
2 python的定制类
3 python中collections库详解
4 Python3的tuple类型
5 Python3的list类型
6 python argparse用法总结

评论列表

取消回复

    •  
      Login

      韩俊

      趁你现在还有时间,尽你自己最大的努力,努力做成你最想做的那件事,成为你最想成为的那种人,过着你最想过的那种生活。这个世界永远比你想的要更精彩,不要败给生活。

      退出登陆
      • 10076文章
      • 455评论
      • 80微语
  • 广告赞助

  • 二零二五年07月
    一二三四五六日
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
  • 分类

    • 网站模板源码
    • IT技术笔记
    • 好资源分享
    • 共享网络资源
  • 最新文章

      • 分享各大最新影视资源采集站网址合集资源共享
        • 经典的黄句子
          • 迷雾通:免费使用的VPN软件
            • 宝塔如何配置SSH密钥,并使用WinSCP工具远程连接服务器
              • 女人高情商祝福语简短
                • 京东外卖商户入驻指南及详细入驻攻略
                  • git教程及git常用命令指南
                    • 七一活动经典句子
  • 热门文章

    • 酷狗音乐VIP账号 酷狗音乐会员账号共享2017.01.29更新
    • 芒果tv vip会员账号 芒果tv会员账号共享2017.01.29更新
    • 爱奇艺vip账号 爱奇艺/PPS会员账号共享2016.12.12更新
    • 优酷/土豆vip会员账号 优酷会员账号共享2017.01.29更新
    • 活动:免费获得爱奇艺VIP/PPS会员账号50天以上的使用权!
    • 酷我音乐VIP账号 酷我音乐会员账号共享2016.12.31更新
    • 暴风影音会员账号 暴风影音会员账号共享2016.12.31更新
    • m1905会员账号 m1905会员账号共享2016.10.21更新
  • 最新评论

    • https://www.vipshare8.com/content/templates/meta/Static/images/tx/10.jpg

      你丫的 文章写得太好了 支持下!![F3...

    • https://www.vipshare8.com/content/templates/meta/Static/images/avatar.jpg

      很棒!刚在某网站看到这个,很欣赏,可惜下...

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=3861064027

      呃呃呃 oooo

    • https://www.vipshare8.com/content/uploadfile/202103/thum-490d1614564497.png

      回复了111:根据激活的时间有一年的有效期!

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=792480561

      到2025就到期了吗?

    • https://www.vipshare8.com/content/uploadfile/202103/thum-490d1614564497.png

      [blockquote]打卡时间:16:...

    • https://www.vipshare8.com/content/templates/meta/Static/images/tx/7.jpg

      俊哥,想借用迅雷一用!但需要手机验证!看...

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=3293901900

      感谢大大的分享

    • https://www.vipshare8.com/content/uploadfile/202103/thum-490d1614564497.png

      回复了好奥v:如果没有解析成功,可以切换接口...

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=131241242441

      现在视频解析网站怎么用不了啦?

  • 网站统计 I 当前在线:869人

    • 本站管理:1位
    • 用户总数:593位
    • 置顶文章:2篇
    • 日志总数:10076篇
    • 微语总数:80条
    • 评论总数:455条
    • 标签总数:83条
    • 页面总数:8页
    • 分类总数:14个
    • 链接总数:16条
    • 运行天数:3716天
    • 最后更新:7月1日
    • 登录
    • 注册
    • 找回
    Copyright © 2025vip共享吧网站地图 网站备案豫ICP备19004194号-1

    免责声明:本站资源仅供用于学习和交流,本站部分素材内容来源于网络,如有侵权/投稿等,请及时联系站长.

    • 首页
    • 秒懂百科 秒懂百科
    • 搜索
    • 史上今日

    大家都在搜

    • seo
    • 暴风影音会员账号
    • 好省
    • 千图网会员账号共享
    • 飞卢小说vip账号共享
    • 飞卢小说会员账号
    • 土豆vip账号共享
    • 爱奇艺VIP账号共享
    • 秒懂百科
    • 哔哩哔哩vip会员账号
    • 电影抢先看
    • MySql
    • 咪咕会员账号
    • 千图网vip账号共享
    • 2345网址导航
    • 优酷账号共享
    • 
    • 