一、面向对象技术简介

  • 类(class):用来描述具有相同属性和方法的对象集合,定义了该集合中每个对象所共有的属性和方法;对象是类的实例

  • 方法:即类中定义的函数

  • 类变量:类变量即在类中声明的变量,其在整个实例化的对象中是公用的,类变量定义在类中且在函数体之外;类变量通常不作为实例变量使用

  • 数据成员:数据成员指类变量或者实例变量用于处理类及其实例对象的相关的数据;

  • 方法重写:当父类继承的方法不能满足子类需求时,可对父类方法进行重写,这个过程叫方法的覆盖(override),也称为方法的重写;

  • 局部变量:局部变量即定义在方法中的变量,只作用于当前实例的类;

  • 实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量;

  • 继承:即一个派生类(derived class)继承基类(base class)的属性和方法;继承允许把一个派生类的对象作为一个基类对象对待;类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法;

  • 实例化:创建一个类的实例,类的具体对象;

  • 对象:通过类定义的数据结构实例,对象包括两个数据成员(类变量和实例变量)和方法;对象可以包含任意数量和类型的数据;

二、类定义

定义一个类的语法格式如下:

class ClassName:<statement_1>...<statement_N>

注意:定义一个类,类的名称后不能有括号()

三、类对象和类实例化

类对象支持两种操作:属性引用和实例化;

类实例化一般使用ClassName()实现,类实例化后可以使用ClassName.value和ClassName.fun()访问属性和方法

类对象实例化后,ClassName.value无法访问局部变量

# 1、类的实例化
class Student:# 类变量age = 20;def student(self):# 局部变量# 类对象实例化后,ClassName.value无法访问局部变量name = 'Kobe'return "我是一个好学生~~"# 类实例化
student = Student()
# 访问类变量
print("访问类变量age:" , student.age)
# 访问类方法
print("访问类方法:" , student.student())

四、构造方法

类中可以定义一个名为 __init__() 的特殊方法(即构造方法),构造方法通常在类实例化时会被自动调用,构造方法(__init__() )可传入参数,参数通过 __init__() 传递到类的实例化操作上;

# 2、构造方法
class Student_2:def __init__(self , studentname , studentage):self.name = studentnameself.age = studentageprint("构造函数__init()__在类实例化时被调用")
# 实例化对象,传入参数;构造函数在实例化时被调用
stu = Student_2("Kobe" , 24)
# 访问构造函数的变量
print("构造函数__init()__中的变量studentname:" , stu.name)
print("构造函数__init()__中的变量studentage:" , stu.age)
构造函数__init()__在类实例化时被调用
构造函数__init()__中的变量studentname: Kobe
构造函数__init()__中的变量studentage: 24

五、类的方法

在类的内部,使用 def 关键字定义类的方法,与一般函数定义不同的是类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例,而不是一个类

# 3.1、self代表类的实例对象,而非类本身
class Test:def prt(self):print("sele参数:" , self)print("seles.__class__参数:" ,self.__class__)t = Test()
t.prt()
sele参数: <__main__.Test object at 0x7f3f160e47f0>
seles.__class__参数: <class '__main__.Test'>
# 3、类的方法
class People:# 定义类变量age = 0name = ""# 定义私有变量,私有属性在类外部无法直接进行访问__height__ = 0# 定义构造方法,构造方法在类实例化时被调用def __init__(self , name , age , height):self.peopleage = ageself.peoplename = nameself.__peopleheight__ = heightdef speak(self):print("%s 说,我已经 %d 岁了,%d 公斤了哦~~" % (self.peoplename , self.peopleage , self.__peopleheight__))# 类实例化,同时传入参数
people = People('Gavin' , 1 , 10)
people.speak()
Gavin 说,我已经 1 岁了,10 公斤了哦~~

六、单继承

Python支持类的继承,语法为:

class DerivedClassName(BasicClassName)<statement_1>...<statement_N>

基类(BasicClass)必须与派生类(DerivedClass)定义在同一个作用域内;

当基类(BasicClass)定义在某个模块时,派生类的定义可以使用表达式,如:

class DerivedClassName(modename.BasicClassName)<statement_1>...<statement_N>
# 4、类的继承
# 定义基类
class People():# 定义全局变量age = 0name = ''# 定义私有属性,私有属性在类外部无法直接进行访问__hight = 0# 定义构造方法def __init__(self , n , a , h):self.name = nself.age = aself.__hight = h# 定义父类方法def PeopleIntroduce(self):print("大家好,我的名字是$s , 我今年%d 岁" % (self.name , self.age))# 定义派生类,继承父类
class Student(People):# 定义派生类的变量male = ""# 定义子类的构造方法def __init__(self , n , a , h , m):# 调用父类的构造方法,传入参数People.__init__(self , n , a , h)# 子类构造方法参数传值self.male = m# 重写父类的方法def StudentIntroduce(self):print("大家好,我的名字是%s , 我今年%d岁,我是一个%s" % (self.name , self.age , self.male))# 实例化子类,传入参数
student = Student("Daisy" , 1 , 50 , "女宝宝")
# 调用子类方法
student.StudentIntroduce()
大家好,我的名字是Daisy , 我今年1岁,我是一个女宝宝

七、多继承

Python同样支持类的多继承,语法为:

class DerivedClassName(BasicClassName1 , BasicClassName2 , BasicClassName3)<statement_1>...<statement_N>

注意:需要关注圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法

# 5、类的多继承
# 定义People基类
class People():# 定义全局变量age = 0name = ''# 定义私有属性,私有属性在类外部无法直接进行访问__hight = 0# 定义构造方法def __init__(self , name , age , __hight):self.name = nameself.age = ageself.__hight = __hight# 定义父类方法def PeopleIntroduce(self):print("大家好,我的名字是%s , 我今年%d 岁" % (self.name , self.age))# 定义基类Speaker
class Speaker():topic = ''name = ''# 定义构造方法def __init__(self , name , topic):self.name = nameself.topic = topic# 定义基类Speaker的方法def speak(self):print("我叫 %s,我是一个演说家,我演讲的主题是 %s" % (self.name,self.topic))# 定义派生类,多继承People和Speaker类
class Sample(People , Speaker):# 定义构造方法def __init__(self , name , age , __height , topic):# 调用父类的构造方法,传入参数People.__init__(self , name , age , __height)Speaker.__init__(self , name , topic)# 实例化多继承子类,传入参数
test = Sample("Daisy",1,50,"Python")
# 调用父类Speaker的方法speak
test.speak()
# 调用父类People的方法PeopleIntroduce
test.PeopleIntroduce()
我叫 Daisy,我是一个演说家,我演讲的主题是 Python
大家好,我的名字是Daisy , 我今年1 岁

八、方法重写

子类继承父类后,如父类方法无法满足子类需求,子类可对父类方法进行重写

# 八、方法重写# 定义父类Parent
class Parent:# 定义父类方法def myMethod(self):print('我调用的是父类方法')# 定义子类,继承父类
class Child(Parent):# 子类重写父类方法def myMethod(self):print('我调用的是子类方法')# 子类实例化
c = Child()
# 子类调用重写方法
c.myMethod()
# 用子类对象调用父类已被覆盖的方法
super(Child, c).myMethod()
我调用的是子类方法
我调用的是父类方法

九、关于Python中子类继承父类构造函数的场景说明

9.1、子类需要自动调用父类的构造方法:子类不重写__init__()方法,实例化子类时,会自动调用父类的__init__()的方法

# 九、关于Python中子类继承父类构造函数的场景说明
# 9.1、子类需要自动调用父类的构造方法:子类不重写__init__()方法,实例化子类时,会自动调用父类的__init__()的方法
# 定义父类Father
class Father:# 定义父类构造方法def __init__(self , name):self.name = nameprint("父类构造方法被执行,name是:" , name)# 定义父类方法def getName(self):return "父类getName函数被执行" + self.name# 定义子类Son,继承父类Father,子类未重写父类构造函数
class Son(Father):# 定义子类方法def getName(self):return "子类getName函数被执行" + self.name# 初始化子类,会调用父类的构造方法
son = Son("Kobe")
print(son.getName())
父类构造方法被执行,name是: Kobe
子类getName函数被执行Kobe

9.2、子类不需要自动调用父类的方法:子类重写父类__init__()方法,实例化子类时,将不会自动调用父类的__init__()的方法

# 九、关于Python中子类继承父类构造函数的场景说明
# 9.2、子类不需要自动调用父类的方法:子类重写父类__init__()方法,实例化子类时,将不会自动调用父类的__init__()的方法
# 定义父类Father
class Father:# 定义父类构造方法def __init__(self , name):self.name = nameprint("父类构造方法被执行,name是:" , name)# 定义父类方法def getName(self):return "父类getName函数被执行" + self.name# 定义子类Son,继承父类Father,子类重写父类构造函数
class Son(Father):# 重写父类构造方法def __init__(self,name):self.name = nameprint("子类重写父类构造方法,name是:" , name)# 定义子类方法def getName(self):return "子类getName函数被执行" + self.name# 初始化子类,不会调用父类的构造方法
son = Son("Kobe")
print(son.getName())
子类重写父类构造方法,name是: Kobe
子类getName函数被执行Kobe

9.3、子类重写父类的__init__()方法,又需要调用父类的方法时,可使用super关键词;

语法:

super(子类,self).__init__(参数1,参数2,....)

或者:

父类名称.__init__(self,参数1,参数2,...)
# 九、关于Python中子类继承父类构造函数的场景说明
# 9.3、子类重写父类的__init__()方法,又需要调用父类的方法时,可使用super关键词
# 定义父类Father
class Father:# 定义父类构造方法def __init__(self , name):self.name = nameprint("父类构造方法被执行,name是:" , name)# 定义父类方法def getName(self):return "父类getName函数被执行" + self.name# 定义子类Son,继承父类Father,子类重写父类构造函数,子类调用父类构造方法
class Son(Father):# 重写父类构造方法def __init__(self,name):# 调用父类构造方法一:super(Son, self).__init__(name)# 调用父类构造方法二:Father.__init__(self , name)self.name = name# 重写父类构造方法print("子类重写父类构造方法,name是:" , name)# 定义子类方法def getName(self):return "子类getName函数被执行" + self.name# 初始化子类,会调用父类的构造方法
son = Son("Kobe")
print(son.getName())
父类构造方法被执行,name是: Kobe
父类构造方法被执行,name是: Kobe
子类重写父类构造方法,name是: Kobe
子类getName函数被执行Kobe

十、super()函数

super() 函数是用于调用父类(超类)的一个方法;super()方法一般用来解决多重继承问题,直接使用类名.方法名的方式调用父类方法的方式,当子类单继承父类时是可行的,但如果子类是多继承时,会涉及到查找顺序(MRO)、重复调用(钻石继承)等问题;MRO 是类的方法解析顺序表, 即继承父类方法时的顺序表;

语法:

super(type[, object-or-type])

参数:

  • type -- 类;
  • object-or-type -- 类,一般是 self,即类的实例,如super(Child , child)
# 十、super()方法
# 例子一:super()函数调用父类中被覆盖的方法
class Father:def work(self):print('我是Father类,我被调用了~')class Child(Father):'''Child类继承Father类'''def work(self):print('我是Child类,我被调用了~')def super_work(self):'''调用Child类自己的work方法'''self.work()  # Child.work被调用,调用自身类的方法,和调用属性一样# 借助super调用父类被覆盖的方法super(Child, self).work()  # Father.work被调用super().work()  # Father.work被调用,这种必须在方法内使用,可以省略(自身类)参数# 實例化Child
child = Child()
child.work()  # Child.work被调用,调自身的类
super(Child, child).work()  # Father.work被调用(使用super是调用Child的父类)
child.super_work()  # 調用child的方法
#super().work()  # RuntimeError: super(): no arguments 不知道调用谁,此种省略参数的只能在内部使用
我是Child类,我被调用了~
我是Father类,我被调用了~
我是Child类,我被调用了~
我是Father类,我被调用了~
我是Father类,我被调用了~
# 十、super()方法
# 例子二:super()函数调用父类中被覆盖的构造方法
class Human:def __init__(self, name, age):self.name = nameself.age = ageprint('父类Human初始化的方法被调用了')def infos(self):print('姓名', self.name)print('年龄', self.age)class Student(Human):def __init__(self, n, a, s=0):# 调用父类的初始化方法之方法一,子类内部调用父类方法时使用selfsuper(Student, self).__init__(n, a)# 调用父类的初始化方法之方法二,内部省略参数super().__init__(n, a)# 增加一个属性self.score = sprint('子类Student的初始化方法被调用了')# 父类方法的重写def infos(self):# 显示调用父类的方法之方法一super().infos()# 显示调用父类的方法之方法二super(Student,self).infos()print('成绩是:', self.score)# 子类实例化时调用子类构造方法(子类构造方法又调用了两次父类构造方法)
student = Student('张三', 20, 80)
# 调用子类的infos()方法(子类infos()方法又调用了两次父类infos()方法,同时打印score属性)
student.infos()
# super()调用父类infos()方法,子类已被初始化时,子类外部调用父类方法时使用子类实例化对象
super(Student,student).infos()
# RuntimeError: super(): no arguments 不知道调用谁,此种省略参数的用法只能在类的内部使用
# super().infos()
父类Human初始化的方法被调用了
父类Human初始化的方法被调用了
子类Student的初始化方法被调用了
姓名 张三
年龄 20
姓名 张三
年龄 20
成绩是: 80
姓名 张三
年龄 20

十一、类的属性和方法

11.1、类的私有属性

定义方式:类的私有属性使用__private_attribute定义,两个下划线开头,表明该属性为类的私有属性

使用范围:私有属性不能在类的外部被直接访问或使用,类内部的方法中使用self.__private_attrs访问或使用私有属性

11.2、类的共有属性

定义方式:类的共有属性使用Common_attribute定义,表明该属性为类的共有属性

使用范围:共有属性可以在类的外部被直接访问或使用,类内部的方法中使用self.Common_attribute访问或使用共有属性

11.3、类的私有方法

定义方式:类的私有方法使用__private_method定义,两个下划线开头,表明该方法为类的私有方法

使用范围:私有方法不能在类的外部被直接访问或使用,类内部的方法中使用self.__private_method访问或使用私有方法

11.4、类的共有方法

定义方式:在类的内部一般使用 def 关键字来定义一个方法,与常规函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定使用 self

默认情况下,Python中的函数和变量都是公开的(public),在python中没有类似public、private等关键词来修饰函数和变量;

在python中定义私有变量只需要在变量名或函数名前加上 ”__“两个下划线;
在python内部,python使用一种 name mangling 技术,将 __membername替换成 _classname__membername,也就是说,类的内部定义中,所有以双下划线开始的名字都被"翻译"成前面加上单下划线和类名的形式;

例如:为了保证不能在class之外访问私有变量,Python会在类的内部自动的把语法定义的__spam私有变量的名字替换成为
_classname__spam(注意classname前面是一个下划线,spam前是两个下划线),因此,用户在外部访问__spam的时候就会
提示找不到相应的变量;

注意:Python中,类的外部访问私有属性和方法的办法是:

私有变量:实例._类名__变量名
私有方法:实例._类名__方法名()
"""
十一、类的属性和方法
1、类的私有属性
2、类的私有方法
3、类的共有属性
4、类的共有方法
"""
# 定义一个类
class Student:# 定义构造函数def __init__(self, name, age):# 定义类的私有属性self.__name = name# 定义类的共有属性self.age = age# 定义类的私有方法def __private_Introduce(self):print("这是类的私有方法__private_Introduce")return "类的私有方法执行Done"# 定义类的共有方法def score(self):print("这是类的共有方法score")# 类的内部调用私有和共有属性print("私有属性__name:" , self.__name)print("共有属性age:", self.age)# 定义类的共有方法def Introduce(self):print("这是类的共有方法Introduce")# 类的内部调用私有方法self.__private_Introduce()# 类的内部调用共有方法self.score()# 实例化类
student = Student("Kobe" , 41)
# 类的外部调用共有方法
student.Introduce()
# 类的外部调用私有属性
print("类的外部调用私有属性__name:" , student._Student__name)
# 类的外部调用私有方法
print("类的外部调用私有方法__private_Introduce:" , student._Student__private_Introduce())
这是类的共有方法Introduce
这是类的私有方法__private_Introduce
这是类的共有方法score
私有属性__name: Kobe
共有属性age: 41
类的外部调用私有属性__name: Kobe
这是类的私有方法__private_Introduce
类的外部调用私有方法__private_Introduce: 类的私有方法执行Done
11.5、Python中下划线的使用场景
  • _xxx: "单下划线" 开始的变量叫做保护变量,意思是只有类实例和子类实例能访问到这些变量, 需通过类提供的接口进行访问;不能用'from module import *'导入;
  • __xxx: "双下划线",类中的私有变量/方法名,意思是只有父类对象自己能访问,连子类对象也不能访问到这个数据;
  • __xxx__:系统定义名字,前后均有一个“双下划线” ,代表python里特殊方法专用的标识,如 __init__()代表类的构造函数;
"""
"单下划线"开始的成员变量叫做保护变量,意思是只有类实例和子类实例能访问到这些变量,
需通过类提供的接口进行访问;不能用'from module import *'导入
"""
class people():# 定义私有变量__place = "nanjing"# 定义保护变量_age = 20def __init__(self, name):self.name = name# 定义保护方法def _test(self):print("定义保护方法_test")return "保护方法执行Done"# 定义私有方法def __sayhello(self):print("%s say hello" % self.name)# 定义子类,继承父类
class teacher(people):pass# 实例化子类
t1 = teacher("Kobe")
# 子类实例访问保护变量
print("子类实例访问保护变量_age:" , t1._age)
print("父类实例访问保护变量_age:" , people._age)
print("子类实例访问保护变量_test():" , t1._test())
# 传入对象t1
print("父类实例访问保护变量_test():" , people._test(t1))
子类实例访问保护变量_age: 20
父类实例访问保护变量_age: 20
定义保护方法_test
子类实例访问保护变量_test(): 保护方法执行Done
定义保护方法_test
父类实例访问保护变量_test(): 保护方法执行Done

十二、类的专有方法

  • __init__ : 构造函数,在生成对象时调用
  • __del__ : 析构函数,释放对象时使用
  • __repr__ : 打印,转换
  • __setitem__ : 按照索引赋值
  • __getitem__: 按照索引获取值
  • __len__: 获得长度
  • __cmp__: 比较运算
  • __call__: 函数调用
  • __add__: 加运算
  • __sub__: 减运算
  • __mul__: 乘运算
  • __truediv__: 除运算
  • __mod__: 求余运算
  • __pow__: 乘方

十三、运算符重载

Python支持运算符重载,可对类的专有方法进行重载

参考文档:

https://blog.csdn.net/geek_xiong/article/details/82598228

# 十三、运算符重载
class Vector:def __init__(self, a, b):self.a = aself.b = bdef __str__(self):return 'Vector (%d, %d)' % (self.a, self.b)def __add__(self, other):return Vector(self.a + other.a, self.b + other.b)v1 = Vector(2, 10)
v2 = Vector(5, 2)
print(v1 + v2)
Vector (7, 12)

十四、类属性、实例属性和私有属性的使用

Python中的属性分为类属性和对象(实例)属性

类属性:属于类所有,可以直接使用类名.属性名调用类属性;类的属性在内存中只有一份

对象(实例)属性:就是在构造方法__init()__中初始化的属性

对象属性属于类的对象所有,可以使用对象名.属性名调用对象属性,不能使用类名.属性名调用,因为实例属性只有在实例创建时,才会初始化创建。

# 14.1、类属性和实例属性的调用关系
class Person:# 定义一个类属性country = "中国"# 定义构造方法def __init__(self , name , age):# 定义对象属性self.name = nameself.age = agesex = "男" #这不是实例属性,仅是变量,使用对象名.sex无法调用# 使用类名.属性名调用类属性
print("使用类名.属性名调用类属性:" , Person.country)
# 无法使用类名.属性名调用对象属性
#print("无法使用类名.属性名调用对象属性:" , Person.name) # 出错,AttributeError: type object 'Person' has no attribute 'name'
# 类实例化,person为类对象
person = Person("Kobe" , 41)
# 类对象使用对象名.属性名调用类属性
print("类对象使用对象名.属性名调用类属性:" , person.country)
# 类对象使用对象名.属性名调用对象属性
print("类对象使用对象名.属性名调用对象属性:" , person.name)
# 输出类对象,其实就是输出该类的内存地址
print("输出类对象:" , person)
使用类名.属性名调用类属性: 中国
类对象使用对象名.属性名调用类属性: 中国
类对象使用对象名.属性名调用对象属性: Kobe
输出类对象: <__main__.Person object at 0x7f236981eef0>

修改类属性和实例属性:类属性只能通过类名.属性才可以修改;对象属性可以使用类名.属性和对象名.属性名修改

# 14.2、修改类属性和实例属性:类属性只能通过类名.属性才可以修改
class Person:# 定义一个类属性country = "中国"# 定义构造方法def __init__(self, name, age):# 定义对象属性self.name = nameself.age = agesex = "男"  # 这不是实例属性,仅是变量,使用对象名.sex无法调用# 类实例化,person1为类对象
person1 = Person("Kobe" , 41)
# 通过实例去修改属性,实例的属性修改为中国香港
person1.country = "中国香港"
print("通过对象名.属性名修改类属性:" , person1.country)
# 通过类名.属性名调用类属性,但是类的属性还是没有修改,仍为中国
print("通过类名.属性名调用类属性:" , Person.country)
# 通过类名.属性名修改类属性,只有使用类名.属性名才能修改类的属性值为"中国台湾"
Person.country = "中国台湾"
# 类实例化,person2为类对象
person2= Person("jackMa",57)
# 通过实例去修改属性,实例的属性修改为中国香港,但是类的属性还是没有修改,仍为中国
print("person1.country:" , person1.country)
print("person2.country:" , person2.country)
print("Person.country:" , Person.country)print("对象名.属性名修改实例属性前person2.name:" , person2.name)
# 对象名.属性名修改实例属性
person2.name = "HAHA"
print("对象名.属性名修改实例属性后person2.name:" , person2.name)
print("对象名.属性名修改实例属性后person1.name:" , person1.name)
# 类名.属性名修改实例属性
Person.name = "饭饭"
print("类名.属性名修改实例属性后Person.name:" , Person.name)
print("类名.属性名修改实例属性后person2.name:" , person2.name)
print("类名.属性名修改实例属性后person1.name:" , person1.name)
通过对象名.属性名修改类属性: 中国香港
通过类名.属性名调用类属性: 中国
person1.country: 中国香港
person2.country: 中国台湾
Person.country: 中国台湾
对象名.属性名修改实例属性前person2.name: jackMa
对象名.属性名修改实例属性后person2.name: HAHA
对象名.属性名修改实例属性后person1.name: Kobe
类名.属性名修改实例属性后Person.name: 饭饭
类名.属性名修改实例属性后person2.name: HAHA
类名.属性名修改实例属性后person1.name: Kobe

十五、私有属性的访问和修改

Python中为了更好的保障属性安全,一般属性的处理方式为:

1、将属性定义为私有属性;

2、添加一个可以调用的方法,供调用;

私有属性的访问和修改方法有:

1、实例._类名__变量名

2、定义set和get方法

# 15、私有属性的访问和修改
class Person(object):# 类属性country = 'china'# 私有类属性,不能直接外部调用__language = "Chinese"# 定义set方法调用私有类属性def setCountry(self , country):self.__country = country# 定义get方法调用私有类属性def getCountry(self):return  self.__countrydef __init__(self, name, age):self.name = name# 使用__下划线表示私有属性,对象不能直接调用,要通过方法调调用self.__age = age# 定义get方法调用私有对象属性def getAge(self):return self.__age# 定义set方法访问修改私有对象属性def setAge(self, age):if age > 100 or age < 0:print("age is not true")else:self.__age = agedef __str__(self):info = "name :" + self.name + ",age(保密):" + str(self.__age)  # 注意这里不是self.agereturn info# ------创建对象,调用方法,属性测试------
stu1 = Person("tom", 18)
print("修改前的结果:", stu1.__str__())
# 修改stu1的name属性
stu1.name = "tom_2"
print("修改name后的结果:", stu1.__str__())
#直接调用私有属性__age报错,'Person1' object has no attribute '__age'
# print(stu1.__age)print("打印私有age内存地址:", id(stu1.getAge()))
# 如果这样赋值的话,不会报错,因为系统找不到这个变量,直接新建了一个,但是实际没有修改对象的属性值
stu1.__age = 19
# 有值,但是没有实际修改stu1对象的age属性值
print(stu1.__age)
# 两个内存地址值不一样
print("打印stu1.__age的内存地:", id(stu1.__age))
# 实际值没有变
print("错误修改age后的值", stu1.__str__())
# 只有调用才可以修改age的值
stu1.setAge(22)
print("正确修改age后的值", stu1.__str__())
print("################")
person = Person("Kobe" , 24)
# 访问私有属性方法一:实例._类名__变量名
print("访问私有属性方法一:实例._类名__变量名,__language:" , person._Person__language)
print("访问私有属性方法一:实例._类名__变量名,__age:" , person._Person__age)
# 修改私有属性方法一:实例._类名__变量名
person._Person__language = "HAHA"
person._Person__age = 1
print("修改私有属性方法一:实例._类名__变量名,__language:" , person._Person__language)
print("修改私有属性方法一:实例._类名__变量名,__age:" , person._Person__age)# 修改和访问私有属性方法二:set和get方法
# set方法修改私有属性
person.setAge(2)
person.setCountry("上海")
# get方法访问私有属性
print("访问私有属性方法二:set和get方法,__language:" , person.getAge())
print("访问私有属性方法二:set和get方法,__age:" , person.getCountry())
修改前的结果: name :tom,age(保密):18
修改name后的结果: name :tom_2,age(保密):18
打印私有age内存地址: 10915040
19
打印stu1.__age的内存地: 10915072
错误修改age后的值 name :tom_2,age(保密):18
正确修改age后的值 name :tom_2,age(保密):22
################
访问私有属性方法一:实例._类名__变量名,__language: Chinese
访问私有属性方法一:实例._类名__变量名,__age: 24
修改私有属性方法一:实例._类名__变量名,__language: HAHA
修改私有属性方法一:实例._类名__变量名,__age: 1
访问私有属性方法二:set和get方法,__language: 2
访问私有属性方法二:set和get方法,__age: 上海

十六、私有方法、类方法和静态方法使用

16.1、私有方法:以 __两个下划线开头,声明该方法为私有方法,私有方法只能在类的内部调用 (类内部别的方法可以调用该私有方法),不能在类地外部调用

类内部私有方法调用:self.方法名

# 16.1私有方法使用
class Person:# 定义私有方法__person1def __person1(self):print("我是私有方法__person1,我被执行了~~")# 定义公共方法person2def person2(self):print("我是共有方法person2,我被执行了~~")# 定义公共方法person3,调用私有和共有方法def person3(self):print("我的共有方法person3,我调用私有和共有方法~~")# 调用共有方法self.person2()# 调用私有方法self.__person1()# 实例化类
person = Person()
# 调用共有方法person2
print("调用共有方法person2:" , person.person2())
# 调用共有方法person3
print("调用共有方法person3:" , person.person3())
# 类的外部无法直接调用私有方法__person1
# 报错信息:AttributeError: 'Person' object has no attribute '__person1'
# print("调用共有方法__person1:" , person.__person1())
我是共有方法person2,我被执行了~~
调用共有方法person2: None
我的共有方法person3,我调用私有和共有方法~~
我是共有方法person2,我被执行了~~
我是私有方法__person1,我被执行了~~
调用共有方法person3: None

16.2、类方法:是类所拥有的方法,需要用修饰器@classmethod来标识其为类方法;类方法的第一个参数必须是类对象,一般以cls作为第一个参数,也可以有别的参数,但是第一个参数必须是类对象,类似类中的def定义的普通方法第一个参数要是self一样的道理

类方法调用:

1、类名.方法名

2、实例化对象名.方法名

# 16.2、类方法使用class People(object):# 定义类属性country = 'china'# 定义类方法,使用装饰器classmethod来进行标识,类方法的第一个参数必须是类对象,一般为cls# 跟普通的方法区别就是可以直接通过类名.方法名的方式调用@classmethoddef getCountry(cls):# 类方法调用类属性return cls.country@classmethoddef sum(cls, a, b):return a + b# 实例化对象
p = People()
# 用实例化对象引用类方法
print("实例化对象引用类方法:" , p.getCountry())
# 通过类名.方法名调用类方法
print("通过类名.方法名调用类方法:" , People.getCountry())
print("实例化对象引用类方法:" , p.sum(10, 11))
print("通过类名.方法名调用类方法:" ,People.sum(10, 11))
实例化对象引用类方法: china
通过类名.方法名调用类方法: china
实例化对象引用类方法: 21
通过类名.方法名调用类方法: 21

16.3、静态方法

使用装饰器@staticmothed标识的方法为静态方法,静态方法不需要多定义参数

静态方法调用:

1、类名.方法名

2、实例化对象名.方法名

# 16.3、静态方法使用class People(object):# 定义类属性country = '中国'# 定义静态方法,使用装饰器staticmethod来进行标识@staticmethoddef getCountry():# 静态方法调用类属性return People.country@staticmethoddef sum(a, b):return a + b# 实例化对象
p = People()
# 用实例化对象引用类方法
print("实例化对象引用静态方法:" , p.getCountry())
# 通过类名.方法名调用类方法
print("通过类名.方法名调用静态方法:" , People.getCountry())
print("实例化对象引用静态方法:" , p.sum(10, 11))
print("通过类名.方法名调用静态方法:" ,People.sum(10, 11))
实例化对象引用静态方法: 中国
通过类名.方法名调用静态方法: 中国
实例化对象引用静态方法: 21
通过类名.方法名调用静态方法: 21

Python3之面向对象相关推荐

  1. python对象编程例子-Python3.5面向对象编程图文与实例详解

    本文实例讲述了Python3.5面向对象编程.分享给大家供大家参考,具体如下: 1.面向过程与面向对象的比较 (1)面向过程编程(procedural programming) 面向过程编程又被称为: ...

  2. [Python3]Python面向对象的程序设计

    [Python3]Python面向对象的程序设计 一.面向对象的程序设计的由来 1.第一阶段:面向机器,1940年以前 最早的程序设计都是采用机器语言来编写的,直接使用二进制码来表示机器能够识别和执行 ...

  3. python编程实例详解-Python3.5面向对象编程图文与实例详解

    本文实例讲述了Python3.5面向对象编程.分享给大家供大家参考,具体如下: 1.面向过程与面向对象的比较 (1)面向过程编程(procedural programming) 面向过程编程又被称为: ...

  4. 【Python3之面向对象的程序设计】

    一.面向对象的程序设计的由来 1.第一阶段:面向机器,1940年以前 最早的程序设计都是采用机器语言来编写的,直接使用二进制码来表示机器能够识别和执行的指令和数据. 简单来说,就是直接编写 0 和 1 ...

  5. python3的面向对象_python3学习之面向对象

    @面向对象 开启博客之路,开始做笔记ing 一,类的创建 1,类的定义 class People: country = 'China' #类变量 def __init__(self,name,sex, ...

  6. 【Python3】面向对象

    文章目录 1. 面向过程 vs 面向对象 1.1 面向过程 1.2 面向对象 2. 类和对象 3. 属性 3.1 类属性 3.2 实例属性 4. 访问控制 5. 方法 5.1 实例方法 5.2 类方法 ...

  7. python3:面向对象(多态和继承、方法重载及模块)

    1.多态 同一个方法在不同的类中最终呈现出不同的效果,即为多态. class Triangle:def __init__(self,width,height):self.width = widthse ...

  8. 【手把手教你】Python面向对象编程入门及股票数据管理应用实例

    1 前言 一般而言,在学习或练习python的初级阶段,在Jupyter Notebook(spyder或pycharm)上进行逐条执行语句和代码,这样可以起到交互的良好效果.但是如果要进行大一点的项 ...

  9. python类的使用方法图解_Python3.5面向对象编程图文与实例详解

    本文实例讲述了Python3.5面向对象编程.分享给大家供大家参考,具体如下: 1.面向过程与面向对象的比较 (1)面向过程编程(procedural programming) 面向过程编程又被称为: ...

最新文章

  1. 连接池Connection Pool 单例设计
  2. rhel dns 配置
  3. 《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #3 如何编写内核模块
  4. 高校寒假时间公布!看完心态稳住…
  5. Duplicate entry ‘‘ for key ‘***‘
  6. 那些远去的人,那段伟大的历史【ZZ】
  7. 重新认识margin-top和margin-bottom
  8. 超市微信小程序怎么做_小程序怎么做的 超市微信小程序怎么做
  9. 多任务学习-Multitask Learning概述
  10. Kubernetes 如何重塑虚拟机
  11. 债券数据集:绿色债券数据集、历时新发、发行债券、DCM定价估值四大指标数据
  12. ov5640帧率配置_vivo S7e游戏测试:三款热门游戏,帧率表现如何?
  13. poi中excel锁定行列问题
  14. 印象笔记,为知笔记和Effie哪个更适合商业机构提案人员?
  15. 计算机停车管理系统界面,智慧停车管理系统-智慧停车整体解决方案
  16. python 算法 小试牛刀
  17. Java中的不可变集合介绍
  18. 精密全波整流电路(利用单电源供电运放)
  19. SAP批次管理-内容概览
  20. 社群规划方案撰写4大步骤

热门文章

  1. 求教,降低APK最低安卓版本限制后,能安装,但打开APP闪退
  2. 什么是SCRM会员积分管理?企业为什么要选择SCRM会员积分管理系统?
  3. [Python-3]Python控制语句
  4. Firefox:曾经打破黑暗的产品
  5. SQL Server 辅助软件系列
  6. 学web前端,看这些书!
  7. 服务器网卡无显示,雨林木风win10系统网络适配器没有显示无线网卡的解决教程...
  8. 讲解卡尔曼滤波附代码讲解
  9. 面试题:设计模式记不住,来看看怎么办?
  10. hash冲突解决办法