专栏首页公众号:googpyPython的类和方法——成员可见性

Python的类和方法——成员可见性

我们继续接着类和对象这个话题聊。

1.类方法

使用装饰器@classmethod。第一参数必须是当前类对象,该参数名一般约定为「cls」,当然cls也可以换成其他名字,通过它来传递类的属性和方法(不能传实例的属性和方法)

如下场景:假设现有一个学生类和班级类,想要实现:执行班级人数增加的操作、获得班级总人数。

class Student():
    sum = 0

    def __init__(self, name, age):  # 构造函数
         self.name = name
         self.age  = age
         self.__class__.sum += 1
         print('当前班级总数为:' + str(self.__class__.sum))

    def do_homework(self):
        print('english homework')

    @classmethod
    def plus_sum(cls):
        cls.sum +=1
        print(cls.sum)

student1 = Student('石敢当',18)
Student.plus_sum()
student2 = Student('喜小乐',18)
Student.plus_sum()
student3 = Student('小明',18)
Student.plus_sum()

2.静态方法

使用装饰器@staticmethod,静态方法是类中的函数,不需要实例。静态方法主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,也就是说在静态方法中,不会涉及到类中的属性和方法的操作。

class Student():
    sum = 0

    def __init__(self, name, age):  # 构造函数
         self.name = name
         self.age  = age
         self.__class__.sum += 1
         print('当前班级总数为:' + str(self.__class__.sum))

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(cls.sum)

    @staticmethod
    def add(x,y):
        print(Student.sum)             #静态方法内部可以访问类方法
        print('This is a static method')

student1 = Student('石敢当',18)
student1.add(1,2)

我的理解是,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。可以用静态方法的地方,都可以用类方法代替。但不要经常使用静态方法,因为和面向对象关联性很弱。

3.成员的可见性:公开和私有

默认情况下,Class内部创建的属性和方法,外部代码是可以通过实例调用直接操作的;但有时候为了保证封装性,我们不希望这些内部属性被外部直接访问。这就需要设置成员可见性。

设置方法:在属性或方法名前面添加两个下划线「__」,成员私有化的作用,确保外部代码不能随意修改对象内部的状态,增加了代码的安全性。

应用场景:定义一个学生类名,在这个类下面,定义分数这个对象,现要给每个学生打一个分数,如果我们允许从外部修改分数,那么如果分数修改为-1时,就与逻辑不符,所以,我们需要通过对变量私有化,以及在类的内部定义一个方法,通过对方法修改变量,就可以对输入的分数做出正确判断。

class Student():
    sum = 0
    def __init__(self, name, age):
         self.name = name
         self.age  = age
         self.__score = 0
         self.__class__.sum += 1

    def marking(self,score):
        if score < 0:
            score = 0                      #不能给别人打负分
        self.__score = score               #公开变量私有化
        print(self.name+'同学本次考试分数为:'+str(self.__score))

student1 = Student('石敢当',18)
student2 = Student('小诺',18)

student1.marking(59)
student1.__score = -1      #公开的public  私有的private   强行赋值
print(student1.__dict__)   
print(student1.__score)    #python动态语言特性

# print(student2.__score)  #报错
print(student2._Student__score)

4.总结

Python中的构造函数前面有双下划线,但它却可以从外部访问,因为在init的后面也有双下划线。所以,我们命名时不推荐使用__name__、__score__这样的形式。

双下划线的实例变量并不是一定不能从外部访问

在上面这段代码中,print(student1.__score)是可以打印出结果的,但print(student2.__score),我们可以通过之前讲过的.__dict__的方法看看内部储存情况。

那么,如果想继续对student2.__score访问,可以将代码改为student2._Student__score就可以实现对__score的访问了,所以说Python本身没有任何机制阻止你干坏事,一切全靠自觉。

本文分享自微信公众号 - googpy(googpy),作者:叫我小包总

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-04-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 常见的Python面试题

    花了两天时间,整理了一些常见的Python面试题,希望对即将参加招聘面试的或者准备转行的同学有一些帮助,临阵磨枪不快也光,大家加油鸭!

    stormwen
  • Window系统下配置Python的环境变量

    今天想用pip安装pyinstaller,本来是件很简单的事,在cmd界面窗口输入pip install pyinstaller就行,结果我输入pip竟然显示:

    stormwen
  • Python的类和对象

    面向对象编程是最有效的软件编写方法之一。在面向对象编程中,你编写表示现实世界中的事物和情景的类,并基于这些类来创建对象。理解面向对象编程有助于你像程序员那样看世...

    stormwen
  • day 17 成员

        def __init__(self, name, id, gender, birth):

    用户2398817
  • 面向对象的三大特性(封装、继承、多态)

    继承 什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 python中类...

    用户1214487
  • Python 魔术方法,属性,迭代器

    Python知识大全
  • python面向对象(一)

                    def __init__(self, 参数)  参数一般作为属性设置给对象. 对象就是self, 对属性的封装.

    用户2398817
  • python面向对象之继承与派生

    python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,...

    菲宇
  • [Python3]Python面向对象

    最早的程序设计都是采用机器语言来编写的,直接使用二进制码来表示机器能够识别和执行的指令和数据。

    用户2398817
  • 测试面试题集-Python编程题(1)

    使用while循环实现输出2 - 3 + 4 - 5 + 6 ... + 100 的和。

    ITester软件测试小栈

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动