1. 创建自己的类

学习面向对象的第一步,就是创建一个类。因为类是面向对象的基石。Python类和其他编程语言(Java、C#等)的类差不多,也需要使用class关键字。下面通过一个实际的例子来看一下Python类是如何创建的。

本例会创建一个类,以及利用这个类创建两个对象,并调用其中的方法。

 # 创建一个Person类
class Person:
# 定义setName方法
def setName(self, name):
self.name = name
# 定义getName方法
def getName(self):
return self.name
# 定义greet方法
def greet(self):
print("Hello, I'm {name}.".format(name = self.name)) # 创建Person对象
person1 = Person()
# 创建Person对象
person2 = Person()
# 调用person1对象的setName方法
person1.setName("Bill Gates")
# 调用person2对象的name属性
person2.name = "Bill Clinton"
# 调用person1对象的getName方法
print(person1.getName())
# 调用person1对象的greet方法
person1.greet()
# 调用person2对象的属性
print(person2.name)
# 调用person2对象的greet方法,另外一种调用方法的方式
Person.greet(person2)

程序运行结果如下图所示。

从上面的代码我们可以了解到Python类的如下知识点。

  • Python类使用class关键字定义,类名直接跟在class关键字的后面。
  • 类也是一个代码块,所以类名后面要跟着一个冒号(:)。
  • 类中的方法其实就是函数,定义的方法也完全一样,只是由于函数定义在类的内部,所以为了区分,将定义在类内部的函数称为方法。
  • 我们可以看到,每一个方法的第1个参数都是self,其实这是必须的。这个参数名不一定叫self(可以叫abc或任何其他名字),但任意一个方法必须至少指定一个self参数,如果方法中包含多个参数,第1个参数将作为self参数使用。在调用方法时,这个参数的值不需要自己传递,系统会将方法所属的对象传入这个参数。在方法内部可以利用这个参数调用对象本身的资源,如属性、方法等。
  • 通过self参数添加的name变量是Person类的属性,可以在外部访问。本例设置了person2对象的name属性的值,与调用person2.setName方法的效果完全相同。
  • 使用类创建对象的方式与调用函数的方式相同。在Python语言中,不需要像Java一样使用new关键字创建对象,只需要用类名加上构造方法(在后面的章节会详细介绍)参数值即可。
  • 调用对象的方法有两种方式,一种是直接通过对象变量调用方法,另一种是通过类调用方法,并且将相应的对象传入方法的第1个参数。在本例中使用了Person.greet(person2)的方式调用了person2对象中的greet方法。

如果使用集成开发环境,如PyDev、PyCharm,那么代码编辑器也会对面向对象有很好的支持,例如,当在对象变量后输入一个点(.)后,IDE会为我们列出该对象中所有可以调用的资源,包括方法和属性,如下图所示。

2.方法和私有化

Python类默认情况下,所有的方法都可以被外部访问。不过像很多其他编程语言,如Java、C#等,都提供了private关键字将方法私有化,也就是说只有类的内部方法才能访问私有化的方法,通过正常的方式是无法访问对象的私有化方法的(除非使用反射技术,这就另当别论了)。不过在Python类中并没有提供private或类似的关键字将方法私有化,但可以曲线救国。

在Python类的方法名前面加双下划线(__)可以让该方法在外部不可访问。

 class Person:
# method1方法在类的外部可以访问
def method1(self):
print("method1")
# __method2方法在类的外部不可访问
def __method2(self):
print("method2") p = Person()
p.method1()
p.__method2() # 抛出异常

如果执行上面的代码,会抛出如下图所示的异常信息,原因是调用了私有化方法method2。

其实“method2”方法也不是绝对不可访问。Python编译器在编译Python源代码时并没有将“method2”方法真正私有化,而是一旦遇到方法名以双下划线(__)开头的方法,就会将方法名改成“ClassNamemethodName”的形式。其中ClassName表示该方法所在的类名,“methodName”表示方法名。ClassName前面要加上但单下划线()前缀。

对于上面的代码,Python编译器会将“method2”方法更名为“_Personmethod2”,所以在类的外部调用“method2”方法会抛出异常。抛出异常的原因并不是“method2”方法被私有化了,而是Python编译器把“method2”的名称改为“_Personmethod2”了。当我们了解了这些背后的原理,就可以通过调用“_Personmethod2”方法来执行“method2”方法。

 p = Person()
p._Person__method2() # 正常调用“__method2”方法

本例会创建一个MyClass类,并定义两个公共的方法(getName和setName)和一个私有的方法(outName)。然后创建了MyClass类的实例,并调用了这些方法。为了证明Python编译器在编译MyClass类时做了手脚,本例还使用了inspect模块中的getmembers函数获取MyClass类中所有的成员方法,并输出方法名。很显然,“outName”被改成了“_MyClass__outName”。

 class MyClass:
# 公共方法
def getName(self):
return self.name
# 公共方法
def setName(self, name):
self.name = name
# 在类的内部可以直接调用私有方法
self.__outName()
# 私有方法
def __outName(self):
print("Name = {}".format(self.name)) myClass = MyClass()
# 导入inspect模块
import inspect
# 获取MyClass类中所有的方法
methods = inspect.getmembers(myClass, predicate=inspect.ismethod)
print(methods)
# 输出类方法的名称
for method in methods:
print(method[0])
print("------------")
# 调用setName方法
myClass.setName("Bill")
# 调用getName方法
print(myClass.getName())
# 调用“__outName”方法,这里调用了改完名后的方法,所以可以正常执行
myClass._MyClass__outName()
# 抛出异常,因为“__outName”方法在MyClass类中并不存在
print(myClass.__outName())

程序运行结果如下图所示。

从getmembers函数列出的MyClass类方法的名字可以看出,“_MyClassoutName”被绑定到了“outName”方法上,我们可以将“_MyClassoutName”看做是“outName”的一个别名,一旦为某个方法起了别名,那么原来的名字在类外部就不可用了。MyClass类中的getName方法和setName方法的别名和原始方法名相同,所以在外部可以直接调用getName和setName方法。

Python从菜鸟到高手(18):类与方法的私有化的更多相关文章

  1. Python从菜鸟到高手(1):数字

    本文主要内容: 1. 数字的基础知识 2. 大整数 3. 二进制.八进制和十六进制 4 数字的格式化输出 一.数字的基础知识 Python语言与其他编程语言一样,也支持四则运算(加.减.乘.除),以及 ...

  2. 《Python从菜鸟到高手》已经出版,开始连载了,购买送视频课程

    好消息,<Python从菜鸟到高手>已经出版!!!   JetBrains官方推荐图书!JetBrains官大中华区市场部经理赵磊作序!送2400分钟同步视频课程!500个案例,400道P ...

  3. Python从菜鸟到高手(6):获取用户输入、函数与注释

    1. 获取用户输入   要编写一个有实际价值的程序,就需要与用户交互.当然,与用户交互有很多方法,例如,GUI(图形用户接口)就是一种非常好的与用户交互的方式,不过我们先不讨论GUI的交互方式,本节会 ...

  4. Python从菜鸟到高手(5):数字

    1 基础知识   Python语言与其他编程语言一样,也支持四则运算(加.减.乘.除),以及圆括号运算符.在Python语言中,数字分为整数和浮点数.整数就是无小数部分的数,浮点数就是有小数部分的数. ...

  5. Python从菜鸟到高手(3):声明变量

    变量(variable)是Python语言中一个非常重要的概念.变量的主要作用就是为Python程序中的某个值起一个名字.类似于"张三"."李四"." ...

  6. Python从菜鸟到高手(2):清空Python控制台

    执行python命令会进入Python控制台.在Python控制台中可以用交互的方式执行Python语句.也就是执行一行Python语句,会立刻返回执行结果.   当Python控制台输入过多的Pyt ...

  7. python学习道路(day8note)(抽象类,类的方法,异常处理,socket编程)

    1.#面向对象 #抽象接口 === 抽象类 #就是架构师给你一个架子,你们去写,如果满足不了直接报错 #python2 print("python2---抽象类".center(2 ...

  8. 【Python基础】之函数、类和方法

    一.函数 1. def定义函数 Python Shell: def add(a,b): return a+b >>>add(1,2) 3 def add(a=1,b=2): retu ...

  9. python接口自动化测试二十一:类和方法

    # 类和方法 class Count(): def __init__(self, aaa, bbb): # 初始化 # 可以放公共的参数 print('实例化的时候,会执行init的内容') self ...

随机推荐

  1. svn状态与常见错误

    TortoiseSVN 1.6.16是最后一个目录独立管理自身cache的svn版本(每个目录下都有一个隐藏的.svn文件夹) 之后的版本会则会根目录上统一进行管理(只有根目录下有一个隐藏的.svn文 ...

  2. 用户 'XXX\SERVERNAME$' 登录失败。 原因: 找不到与提供的名称匹配的登录名。 [客户端: ]

    一工厂的中控服务器遇到了下面Alert提示,'XXX\SERVERNAME$'  XXX表示对应的域名, SERVERNAME$(脱敏处理,SERVERNAME为具体的服务器名称+$),而且如下所示, ...

  3. jsp笔记----jsp常用的的获取项目的根路径

    <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" ...

  4. Java线程相关的热门面试题

    ---恢复内容开始--- 下面是Java线程相关的热门面试题,你可以用它来好好准备面试. 1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序 ...

  5. 简单易懂的程序语言入门小册子(5):基于文本替换的解释器,递归,不动点,fix表达式,letrec表达式

    这个系列有个显著的特点,那就是标题越来越长.忽然发现今天是读书节,读书节多读书. ==下面是没有意义的一段话============================================== ...

  6. Windows Server 2016-域站点链接及复制时间调整

    本章简单为大家介绍如何新建域链接并调整复制计划.生产环境中很多情况下需要我们手工去创建站点复制链接,并根据实际带宽情况调整复制计划以减轻网络压力等.站点内部署多台域控制器,域控制器间的 复制链接建议通 ...

  7. spring拦截器(interceptor)简介

    1. 拦截器用途 (1)拦截未登录用户直接访问某些链接 (2)拦截日志信息 (3)拦截非法攻击,比如sql注入 2. 涉及jar.类 (1)spring-webmvc.jar (2)HandlerIn ...

  8. 为什么会出现Notice: Undefined index: submit in D:\xampp\htdocs\test.php on line 19

    事例如下": <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ ...

  9. LeetCode算法题-Binary Watch(Java实现)

    这是悦乐书的第216次更新,第229篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第84题(顺位题号是401).二进制手表顶部有4个LED,代表小时(0-11),底部的6 ...

  10. LeetCode算法题-Lowest Common Ancestor of a Binary Search Tree

    这是悦乐书的第197次更新,第203篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第59题(顺位题号是235).给定二叉搜索树(BST),找到BST中两个给定节点的最低共 ...