【Python进阶(三)】——面向对象编程,建议收藏!
该篇文章首先利用Python展示了其面向对象编程的特性,包括类的定义方法;类中的特殊方法;类之间的集成关系;私有属性极@property装饰器;self和cls;new与init的区别和联系等内容。
1 类的定义方法
运行程序:
class Person: nationality = 'China' #将国际定义为public属性 _deposit=10e10 #python受保护属性名用一个下划线开始 __gender="M" #python私有属性名用两个下划线开始 def __init__(self, name, age): self.name = name age = age def say_hi(self): print(self.name) p1 = Person('Tom', 30)#新建一个新对象并对此进行初始化后得到一个实物p1 p1.say_hi() ##__init__():初始化函数 ##__new__():构造新函数 ##__del__():析构函数
运行结果:
Tom
2 类中的特殊方法
运行程序:
class Person: """ 此处为类Person的docString """ nationality = 'China' _deposit=10e10 __gender="M" def __init__(self, name, age): age = age #age为函数__init__中的局部变量 self.name = name def say_hi(self): print(self.name) @classmethod #类方法的定义方法 def class_func(cls): cls.nationality = 'CHINA' print('I live in {0}'.format(cls.nationality)) @staticmethod #静态方法的定义方法 def static_func(x, y): print(x+y) p1 = Person('Tom', 20) p1.say_hi() Person.static_func(200,300) Person.class_func() p1.class_func()
运行结果:
Tom 500 I live in CHINA I live in CHINA
3 类之间的集成关系
运行程序:
class Teacher(Person): #表示类方法之间的继承关系:在定义一个类时候,将其父名放在类之后的括号中 pass t1=Teacher("zhang",20) Person.class_func() t1.class_func() t1.static_func(1,10) Person.static_func(2,10) t1._deposit t1.__gender #子类不能继承父类的private属性
运行结果:
I live in CHINA I live in CHINA 11 12 100000000000.0
异常信息:
AttributeError Traceback (most recent call last) <ipython-input-73-6ae6e94e243e> in <module> 8 Person.static_func(2,10) 9 t1._deposit ---> 10 t1.__gender #子类不能继承父类的private属性 global t1.__gender = undefined 11 get_ipython().run_line_magic('pinfo', 'Person') 12 get_ipython().run_line_magic('pinfo', 'Teacher') AttributeError: 'Teacher' object has no attribute '__gender'
运行程序:
Person?#查看父类的docString Teacher?#查看类的docString Person.__name__ #获取类名 Person.__doc__ #获取类中字符串 Person.__bases__ #获取类所有父类组成的元组 Person.__dict__ #获取类所有属性和方法组成的类别 Person.__module__ #获取类所在的模块名 Person.__class__ #获取实例所对应的类
运行结果:
'Person' '\n 此处为类Person的docString\n \n ' (object,) mappingproxy({'__module__': '__main__', '__doc__': '\n 此处为类Person的docString\n \n ', 'nationality': 'CHINA', '_deposit': 100000000000.0, '_Person__gender': 'M', '__init__': <function __main__.Person.__init__(self, name, age)>, 'say_hi': <function __main__.Person.say_hi(self)>, 'class_func': <classmethod at 0x2c94b2d2470>, 'static_func': <staticmethod at 0x2c94b2d2358>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>}) '__main__' type
4 私有属性及@property 装饰器
运行程序:
class Student: __name="Zhang" #私有变量 age=18#公共变量 @property#将方法或函数以属性的方式调用 def get_name(self): print(self.__name) stdnt1=Student() #用@property装饰器装饰的函数的调用不能加(),必须通过属性的方式调用 stdnt1.get_name
运行结果:
Zhang
5 self 和 cls
运行程序:
class Student: age=0 name="z" def __init__(self): #在定义一个类时,self代表的是实例的引用 self.name="zhang" age=10 s1=Student() s2=Student() s1.name="song" s1.age=30 Student.age=20 Student.name="li" s1.name, s1.age,s2.name, s2.age
运行结果:
('song', 30, 'zhang', 20)
5 new与init的区别和联系
运行程序:
class Student: name="wang" __age=16 def __new__(cls,name,age): print('new函数被调用') def __init__(self,name,age): print( 'init函数被调用') self.name = name self.age = age def sayHi(self): print(self.name,self.age) s1= Student("zhang", 18) print(s1)#因为__new__()没有return,所以导致s1中的值为NoneType s1.sayHi()
运行结果:
new函数被调用 None --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-88-f90fbe733407> in <module> 15 s1= Student("zhang", 18) 16 print(s1) ---> 17 s1.sayHi() global s1.sayHi = undefined AttributeError: 'NoneType' object has no attribute 'sayHi'
运行程序:
class Student: name="wang" __age=16 def __new__(cls,*args, **kwargs): print('new函数被调用') return object.__new__(cls) def __init__(self,name,age): print( 'init函数被调用') self.name = name self.age = age def sayHi(self): print(self.name,self.age) s1= Student("zhang", 18) s1.sayHi()#当__new__()中return执行后,才会执行__init__() #执行函数__new__()生成对象,执行函数__init__()生成实例
运行结果:
new函数被调用 init函数被调用 zhang 18