学习面向对象的第一步,就是建立一个类。由于类是面向对象的基石。Python类和其余编程语言(Java、C#等)的类差很少,也须要使用class关键字。下面经过一个实际的例子来看一下Python类是如何建立的。html
本例会建立一个类,以及利用这个类建立两个对象,并调用其中的方法。编程
# 建立一个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类的以下知识点。编辑器
若是使用集成开发环境,如PyDev、PyCharm,那么代码编辑器也会对面向对象有很好的支持,例如,当在对象变量后输入一个点(.)后,IDE会为咱们列出该对象中全部能够调用的资源,包括方法和属性,以下图所示。ide
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。3d
其实“method2”方法也不是绝对不可访问。Python编译器在编译Python源代码时并无将“method2”方法真正私有化,而是一旦遇到方法名以双下划线(__)开头的方法,就会将方法名改为“ClassNamemethodName”的形式。其中ClassName表示该方法所在的类名,“methodName”表示方法名。ClassName前面要加上但单下划线()前缀。code
对于上面的代码,Python编译器会将“method2”方法改名为“_Personmethod2”,因此在类的外部调用“method2”方法会抛出异常。抛出异常的缘由并非“method2”方法被私有化了,而是Python编译器把“method2”的名称改成“_Personmethod2”了。当咱们了解了这些背后的原理,就能够经过调用“_Personmethod2”方法来执行“method2”方法。orm
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方法。