python学习笔记----面向对象
面向对象
类:成员变量(属性)
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。方法(操作成员变量)
出一个场景:
玩过游戏。主人公,进入了一个场景,有10个小怪物
是一样的。有攻击力,血(100格)。如果小怪物有
多个数值需要管理,小怪物的血量、小怪物出现在屏幕的地点。 {"blood":100,"location":"10,10"}
[[100,(10,10)]] 10 个小怪物。记住10个小怪物所有的变量在哪里,怎么操作? 写一些函数,来操作这些数据。
函数你实现的时候,你觉得需要实现哪些功能? 10个方法:所有操作的数据的方法 add_blood():
blood+=1 minus_blood():
blood-=1 move():
x-=10
y-=10
class soldier(): #小怪物的类 """小怪物的类""" def __init__(self,blood,location_x,location_y): self.blood = blood self.location_x = location_x self.lcoation_y = location_y def add_blood(self,num): if self.blood<=100: self.blood+=num if self.blood>100: self.blood = 100 def minus_blood(self,num): if self.blood>=0: self.blood-=num if self.blood<0: self.blood = 0 def tell_blood(self): return self.blood s1= soldier(100,10,10) s2= soldier(90,10,20) s3= soldier(80,10,30) print(s1.tell_blood()) print(s2.tell_blood()) print(s3.tell_blood())
类:(相关数据存在一起,并且有一组操作相关数据的方法)
属性(数据)
方法(类里面写的函数叫做方法。)
类比说明:
生产杯子,杯子的模具(类),可以设定不同的参数来
生产杯子。
设定好不同的参数(通过构造函数传参)
生产出具体的杯子(实例化)
类:soldier
实例化:传入不同的参数(调用构造函数)
s1
s2
s3
import math class circle(object): def __init__(self,radius): self.radius = radius def get_area(self): return math.pi*self.radius*self.radius def get_perimeter(self): return 2*math.pi*self.radius for i in range(1,6): a= circle(i) print(a.get_area()) print(a.get_perimeter())
#self.xxxx实例变量 #在类里面定义的函数叫做方法 def add():#函数
return a+b
import math class circle(object): def __init__(self,radius): if radius<=0: self.radius = 1 else: self.radius = radius def modify_radius(self,radius): if radius<0: self.radius = abs(radius) elif radius==0: self.radius = 1 def get_area(self): return math.pi*self.radius*self.radius def get_perimeter(self): return 2*math.pi*self.radius c=circle(-1) print(c.get_area()) c.modify_radius(-2) print(c.get_area())
类:
封装了数据,和操作数据的规则,保证数据的安全。 a=[1,2,3] #只存正数的列表
def set(a,index,new_value):
if new_value>=0:
a[index] = new_value set(a,0,100)
print(a)
set(a,0,-50)
print(a)
a[0]=-50
print(a) class positive_num_list(object):
def __init__(self,a):
self.__value = a
def set(self,index,value):
if value<0:
return
self.__value[index] = value
def get(self):
return self.__value
p= positive_num_list([1,2,3,4])
p.__value[0]=-100
class P: def __init__(self,value): #构造方法,初始化的 self.__value = value #value局部变量 #self.value叫做实例变量 def get(self): #实例方法 return "***:"+str(self.__value) def set(self,value): #实例方法 if isinstance(value,(int,float)): self.__value = value return None
p1 =P(1)
p2 =P(2)
p3 =P(3) p3.set(1,2) #p3的地址传递给了self,1-》value,2是多余的。。 TypeError: set() takes 2 positional arguments but 3 were given
内存中的位置:A
P:类变量
类定义的方法
内存中的位置:b
p1的实例:self.__value=1
内存中的位置:c
p2的实例:self.__value=2
内存中的位置:d
p3的实例:self.__value=3
p1.get()--->会把内存位置b发送给类定义的方法P.get
self:是一个方法的参数,内存位置b。
get方法慧聪从内存b的位置找到,__value值,然后执行
方法中的代码。
self传递的是某个实例的地址。实例地址里面的所有变量
都可以在方法中进行使用。 类中所有定义的方法,类变量,只有一份
实例在内存中:有0个,1个或多个。 类中方法参数包含self的方法:实例方法
每个实例方法,只能操作本实例中的实例变量。
变量前面加有self.的叫做实例变量。
如果不加self.的叫做局部变量 类:
1 可以封装数据,制定数据的存储规则,保证数据的安全
2 类相当于模板,可以通过构造函数做初始化,快速生成实例
3 基于类,可以进行扩展。(设计模式)
4 内存中存储的类变量和方法,只有一份。每个类的实例,都在
内存中有一个地址(类产生的实例可以有0个、1个或多个)
5 类中定义的实例方法(方法中有self参数),可以操作每个
实例中封装的变量
6 实例变量(self.开头的)可以在不同的实例方法中被访问。
实现变量都存在对应的实例所在的内存地址中。
7 __变量是私有变量,除了类中的实例方法可以访问,外部不可以
直接访问和修改。
class P1:#定义类
pass
class P2(object):
pass
p1=P1() #实例化
p2=P2()#实例化
print(p1)
print(p2) 类:
可以把数据放在类的实例里面去管理,
使用类里面的实例方法来管理这些数据,保证数据的安全性 class Person:
def __init__(self,name,age):
if isinstance(age,int) and age >0:
self.age = age
else:
self.age = 0
def set_age(self,age):
if isinstance(age,int) and age >0:
self.age = age
def get_age(self):
return self.age
p1=Person("wulaoshi",18)
p2=Person("lilaoshi",28)
p1.age=-1
print(p1.age) #私有变量不可以被外部访问 class Person:
def __init__(self,name,age):
if isinstance(age,int) and age >0:
self.__age = age
else:
self.__age = 0
def set_age(self,age):
if isinstance(age,int) and age >0:
self.__age = age
def get_age(self):
return self.__age
p1=Person("wulaoshi",18)
p2=Person("lilaoshi",28)
#print(p1.__age)
p1.__age=100#这里相当于重新定义一个__age
print(p1.__age)
print(p1.get_age())#这里获取的是return返回的self.__age

#私有方法:只能是类里面的其他变量可以调用 class Person:
def __init__(self,name,age):
if isinstance(age,int) and age >0:
self.__age = age
else:
self.__age = 0
def set_age(self,age):
if isinstance(age,int) and age >0:
self.__age = age
def __print_age(self):
print(self.__age)
def get_age(self):
self.__print_age()#方法内部调用私有方法前面要加self
return self.__age
p1=Person("wulaoshi",18)
p2=Person("lilaoshi",28)
p1.__print_age()
... pass
...
>>> p=P()
>>> dir(p)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> class Person:
def __init__(self,name):
def get_name(self):#实例方法都要加self
print(
p1=Person("wulaoshi")
p1.get_name()
内存:
类Person放在内存地址:xxxxyyy1
get_name():这个方法的调用要有一个self参数
实例p1放在内存地址:mmmmzzzz2
name=“wulaoshi”
p1.get_name()的调用过程:
1)在xxxxyyy1中先把get_name()的内容找出来
想去调用。
2)实例变量p1的内存地址 --->self=mmmmzzzz2
3)get_name(self=mmmmzzzz2)
4)执行方法体:print(
5)去mmmmzzzz2找到name的值,然后打印
6)完成。 类中的实例方法中的第一个参数self,实际上就是
实例所在内存的地址,通过这个地址,可以找到
实例方法中需要使用的各种实例属性(数据) class Person:
def __init__(self,name):
def get_name(self):#实例方法
print(
def get_name2(self):#实例方法
print(
p1=Person("wulaoshi") #mmmmzzzz2
p1.get_name() #self就是p1的内存地址
p1.get_name2() #self就是p1的内存地址
p2=Person("李老师") #mmmmzzzz3
p2.get_name() ##self就是p2的内存地址
p2.get_name2() #self就是p2的内存地址 类变量和实例变量 class Person:
x=0 #类变量 放在方法外面 全局生效 所有的方法看到的变量只有一个
def __init__(self,name):#只有在实例化才可以调用__init__方法

Person.x+=1
def get_name(self):#实例方法
print(

p1=Person("wulaoshi")#实例化:类名+()+参数
p2=Person("laoli")
p3=Person("laoli")
print(Person.x)#可以用类名访问 也可以用实例名访问 print(p1.x)
print(p2.x) 实例化:p2=Person("laoli")
实例对象:p2
实例方法:get_name
实例变量:

class P:
pass
p=P() 构造函数 class Person:
def __init__(self,name):

p=Person("老王")
print(

def __init__(self,name):

def set_name(self,name):

def get_name(self):
return

class AsianPerson(Person):
def __init__(self,name,nation):
Person.__init__(self,name)#初始化类的实例
self.nation = nation
def set_nation(self,nation):
self.nation = nation
def get_nation(self):
return self.nation
ap= AsianPerson("laowang","china")
print(ap.get_name())
print(ap.get_nation())
ap.set_name("laolaowang")
print(ap.get_name())
p=Person("老李")
print(p.get_name()) 子类想使用父类的方法、变量,则必须在
子类的构造函数中来完成父类实例的构造方法的调用 重写 class Person:#父类
def __init__(self,name):

def set_name(self,name):

def get_name(self):#父类的get_name方法
return

class AsianPerson(Person):#子类
def __init__(self,name,nation): #父类的__init__构造函数,不会被子类所继承
父类其他的共有变量和共有方法,会被子类所继承
Person.__init__(self,name)
self.nation = nation
def get_name(self): #重写了父类中的方法,调用的时候不会在使用父类中的该方法
return "****:"+

ap= AsianPerson("laowang","china")
print(ap.get_name())
重写: 重载: class Person:
def __init__(self,name):
self.__name = name
def set_name(self,name):
self.__name = name
def get_name(self):
return self.__name
class AsianPerson(Person):
def __init__(self,name,nation):
Person.__init__(self,name)
self.nation = nation
ap= AsianPerson("laowang","china")
print(ap.get_name())
print(ap.set_name("laoli"))
print(ap.get_name())
print(ap.__name) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- class Person:
def __init__(self):
self.__name = "laowang"
def set_name(self,name):
self.__name = name
def get_name(self):
return self.__name
class AsianPerson(Person):
def __init__(self,name,nation):
Person.__init__(self)
self.nation = nation
def get_name(self):
return self.__name
ap= AsianPerson("laowang","china")
print(ap.get_name())
如果父类中有私有变量,那么子类的方法是不能读取
父类中的私有变量的 '''
任何东西
1)属性(特征:通常可以用数据来描述)
(类变量和实例变量)
2)可以做一些动作(方法)
类来管理对象的数据。
属性:类变量和实例变量(私有变量)
方法:
1)实例方法
2)类方法
3)静态方法
面向对象和函数管理数据:
类:
专有数据(可以存储,和对外使用)
方法(用于操作专有数据的),实现操作数据的规则。 函数:
无专有数据,谁给他传值都可以处理,并返回
本身不能存储数据。
class compute: def __init__(self,a,b):
self.a = a
self.b = b def add(self):
return self.a+self.b def add(a,b):
return a+b print(add(1,2))
print(compute(1,2).add())
类:作为一个整体,
把一组相关数据放到类的实例里面,进行存储、计算等
实现安全性、独立性,规则的操作统一。
'''
"""
1)实例方法
2)类方法
3)静态方法
"""
'''
class Person:
count = 0 #类变量
nation = "中国" def __init__(self,name,gender):
self.name = name
self.gender = gender
Person.count +=1 def get_name(self):#实例方法,必须要实例化
return self.name #类方法:可以使用类变量,不能使用实例变量
#通过类名来使用,类名.get_instance_count()
#也可以通过实例调用,实例对象.get_instance_count()
@classmethod
def get_instance_count(cls):
return Person.count @classmethod
def create_a_instance(cls):
return Person("张","女") @staticmethod #静态方法:不需要self和cls
def get_nation():
return Person.nation
''' #只能使用一次
#print(Person("吴老师","Male").get_name())
#wulaoshi = Person("吴老师","Male")#实例化
#print(wulaoshi.get_name())
#print(Person.count)
#Person("吴老师","Male")
#print(Person.count)
#print(Person.get_instance_count())
#print(Person.create_a_instance())
print(Person("吴老师","Male").get_instance_count())
print(Person.get_nation())
print(Person("吴老师","Male").get_nation())
'''
三种方法的区别:
1 实例方法,参数要有self,必须通过实例化的对象去调用。
2 类方法,要加上@classmethod来声明,参数至少有一个,
一般定义为cls,可以使用类变量,不能使用实例变量。
通过类名或者实例对象调用。
3 静态方法,要加上@staticmethod来声明,可以没有参数,
使用类变量,不能使用实例变量。
通过类名或者实例对象调用。
''' '''
@staticmethod #静态方法:不需要self和cls
def get_more():
Person.count +=100
return Person.count print(Person("吴老师","Male").get_more())
''' #继承 继承:子类具备所有父类的共有变量和共有方法
如果子类没有定义__init__构造方法,会自动调用父类的。
def __init__(self,name,gender):
self.name = name
self.gender = gender
Person.count +=1
print("创建了一个新的人") def get_name(self):#实例方法,必须要实例化
return self.name class ChinaPerson(Person):
pass #如果子类没有定义__init__构造方法
#会自动调用父类的。 cp = ChinaPerson("吴老师","男")
print(cp.name)
print(cp.gender)
print(cp.get_name())
print(cp.count) 继承:子类具备所有父类的共有变量和共有方法
如果子类没有定义__init__构造方法,会自动调用父类的。
好处:站在老爸的肩膀上,增加属性,增加方法
在原有的基础上进行扩展。 class Person:
count = 0 #类变量
nation = "中国"
def __init__(self,name,gender):

self.gender = gender
Person.count +=1
print("创建了一个新的人")
def get_name(self):#实例方法,必须要实例化
return

class ChinaPerson(Person):
#如果子类没有定义__init__构造方法
#会自动调用父类的。
def __init__(self,name,gender):
Person.__init__(self,name,gender)
def get_gender(self):
return self.gender
cp = ChinaPerson("吴老师","男")
print(cp.count) 多继承 class Person:
count = 0 #类变量
nation = "中国"
def __init__(self,name,gender):

self.gender = gender
Person.count +=1
print("创建了一个新的人")
def get_name(self):#实例方法,必须要实例化
return

class Bird:
def __init__(self,color):
print("a bird is birthed!")
self.color = color
def fly(self):
print("I can fly in the sky!")
class ChinaBirdPerson(Person,Bird):
#如果子类没有定义__init__构造方法
#会自动调用父类的。
def __init__(self,name,gender,color):
Person.__init__(self,name,gender)
Bird.__init__(self,color)
def get_gender(self):
return self.gender
cp = ChinaBirdPerson("吴老师","男","红色")
print(cp.color)
print(cp.get_name())
print(cp.fly())
"""
继承:子类具备所有父类的共有变量和共有方法
如果子类没有定义__init__构造方法,会自动调用父类的。
好处:站在老爸的肩膀上,增加属性,增加方法
在原有的基础上进行扩展。
多继承:在括号里面写上多个基类(父类)
子类的构造函数,如果没有实现,则调用第一个基类的构造
函数。
""" class P:
#def get_name(self):
# return "P name!"
pass
class Person(P):
count = 0 #类变量
nation = "中国"
def __init__(self,name,gender):

self.gender = gender
Person.count +=1
print("创建了一个新的人")
class Bird:
def __init__(self,color):
print("a bird is birthed!")
self.color = color
def fly(self):
print("I can fly in the sky!")
def get_name(self):#实例方法,必须要实例化
return "bird has no name"
class ChinaBirdPerson(Person,Bird):
#如果子类没有定义__init__构造方法
#会自动调用父类的。
def __init__(self,name,gender):
Person.__init__(self,name,gender)
#Bird.__init__(self,color)
def get_gender(self):
return self.gender
cp = ChinaBirdPerson("吴老师","男")
print(cp.get_name())
"""
继承:子类具备所有父类的共有变量和共有方法
如果子类没有定义__init__构造方法,会自动调用父类的。
好处:站在老爸的肩膀上,增加属性,增加方法
在原有的基础上进行扩展。
多继承:在括号里面写上多个基类(父类)ChinaBirdPerson(Person,Bird)
子类的构造函数,如果没有实现,则调用第一个基类的构造
函数。
""" 从父类、爷爷类去查找方法,叫做深度优先
从多继承的同级类去查找方法,叫做广度优先 p -->get_name(爷爷类)
Person(父类) Bird-->get_name(父类)
ChinaBirdPerson(孙类) cp.get_name() class P: class P(): class P(object): 面向对象 python是面向过程和面向对象语言 类:
class P:
x=100
def __init__(self,name):

def print_sth(s):
print(s)
class P1(P):
def print_sth(s):
print(s,s)
类变量:x,首先没有self,定义在方法外。
实例变量:

局部变量:s,name,在函数内有效,出了就不能用了
数据成员(属性):类变量、实例变量
方法的重写:P1类中的print_sth重写了父类P中的print_sth方法
继承:P1继承了P,可以使用P中所有的共有属性和共有方法
实例化:p=P() ,每个实例有自己的内存地址,互相独立
对象:p(包含属性和方法)
实例方法:只能用实例调用
类方法:可以用类名调用,也可以用实例调用
示例:
class Person:"""人类的类"""
x=100
def __init__(self,name): #构造方法
self.name = name #
self.count=123
def get_name(self): #实例方法
return self.name
@classmethod #类方法 装饰器 cls指向类对象
def get_count(cls):
return Person.x p=Person("吴老师")
print(Person.get_count())#类方法可以用类名调用
print(p.get_count())#类方法可以用实例调用
print(p.get_name())
print(Person.get_name())#实例方法不可以用类调用
运行结果:
C:\Users\dell>py -3 C:\Users\dell\Desktop\练习\4\20190411.py
100
100
吴老师
Traceback (most recent call last):
File "C:\Users\dell\Desktop\练习\4\20190411.py", line 21, in <module>
print(Person.get_name())#实例方法不可以用类调用
TypeError: get_name() missing 1 required positional argument: 'self'
为什么非得定义类变量,在普通方法中不是也可以返回吗?
类变量的好处:方便统计所有实例返回的总结果
代码实例:统计每个实例的共工资。
class Person: """人类的类""" x=100 total_salary =0 def __init__(self,name,salary): #构造方法 self.name = name # self.count=123 self.salary =salary Person.total_salary +=salary def get_name(self): #实例方法 return self.name @classmethod #类方法 装饰器 cls指向类对象 def get_count(cls): return Person.x @staticmethod #静态方法 tips:静态方法和类方法的区别:静态方法不加cls def get_total_salary(): return Person.total_salary p1 = Person("吴老师",1000) p1 = Person("张老师",2000) p1 = Person("李老师",3000) print(Person.get_total_salary())
运行结果:
C:\Users\dell>py -3 C:\Users\dell\Desktop\练习\4\20190411.py
6000
为什么要定义类方法,在普通方法中不是也能返回类变量吗?
1 首先能用类名调用的只有:类变量,类方法,静态方法
2 其次,所以类方法可以直接用类名来调用,不需要实例化才能调用。
简单来说,就是不需要实例化的都可以方法类方法或静态方法里。
实例:把常用的函数放到一个类里
import time class Time: @staticmethod def t(): return time.time() print(Time.t())
执行结果:
C:\Users\dell>py -3 C:\Users\dell\Desktop\练习\4\20190411.py
1554990347.386067
总结:
实例方法:方法一个参数是self,要用实例去调用。
类方法:方法第一个参数是cls,可以用实例或者类名去调用。
方法里面不能使用实例变量。@classmethod
静态方法:方法不需要第一个参数,可以用实例或者类名去调用。
方法里面不能使用实例变量。@staticmethod
类里面,可以调用类外面的函数吗?可以
实例1:
import time def add(a,b): return a+b class Time: @staticmethod def t(): return time.time() @staticmethod def t1(): return add(1,2) print(Time.t1())
执行结果:
C:\Users\dell>py -3 C:\Users\dell\Desktop\练习\4\20190411.py
3
实例2:
import time def add(a,b): return a+b def sub(a,b): print(Time.t()) return a-b class Time: @staticmethod def t(): return time.time() @staticmethod def t1(): return add(1,2) print(Time.t1()) print(sub(2,1))
执行结果:
C:\Users\dell>py -3 C:\Users\dell\Desktop\练习\4\20190411.py
3
1554991822.1741009
1
三种方法访问私有类变量,实例:
class Person: __x = 0 #私有类变量 def __init__(self,name): self.name = name Person.__x +=1 def get_count1(self): return Person.__x @classmethod def get_count2(cls): return Person.__x @staticmethod def get_count3(): return Person.__x p = Person("吴老师") print(p.get_count1()) print(Person.get_count2()) print(Person.get_count3())
Person.__x #私有类变量不能在方法外部访问
执行结果:
C:\Users\dell>py -3 C:\Users\dell\Desktop\练习\4\20190411.py
1
1
1
Traceback (most recent call last):
File "C:\Users\dell\Desktop\练习\4\20190411.py", line 23, in <module>
Person.__x
AttributeError: type object 'Person' has no attribute '__x'
私有实例变量,实例:
class Person: __x = 0 def __init__(self,name): self.__name = name #私有实例变量 Person.__x +=1 def get_count1(self): return self.__name p = Person("吴老师") print(p.get_count1()) p.__name #私有实例变量外部不能访问
执行结果:
C:\Users\dell>py -3 C:\Users\dell\Desktop\练习\4\20190411.py
吴老师
Traceback (most recent call last):
File "C:\Users\dell\Desktop\练习\4\20190411.py", line 13, in <module>
p.__name
AttributeError: 'Person' object has no attribute '__name'
可以在类里写一个方法来访问私有变量,实例:
class Person(): def __init__(self,name): self.__name = name def get_name(self): return self.__name def set_name(self,name): self.__name = name p =Person("吴老师") print(p.get_name()) p.set_name("李老师") print(p.get_name())
执行结果:
C:\Users\dell>py -3 C:\Users\dell\Desktop\练习\4\20190411.py
吴老师
李老师
私有方法:只能在类里面使用
实例:
class Person(): def __init__(self,name): self.__name = name def __get_name(self): return self.__name def set_name(self,name): if len(name)>5: return self.__name = name def print_name(self): print(self.__get_name()) p =Person("吴老师") p.print_name() p.__get_name()#外部不可访问
执行结果:
C:\Users\dell>py -3 C:\Users\dell\Desktop\练习\4\20190411.py
吴老师
Traceback (most recent call last):
File "C:\Users\dell\Desktop\练习\4\20190411.py", line 21, in <module>
p.__get_name()
AttributeError: 'Person' object has no attribute '__get_name'
