类(class):一个类是对一类拥有相同属性的对象
对象: 一个对象就是对一个类实例化后的实例,每个类可以实例化多个对象
类有三种特性:封装、继承、多态
封装:在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个容器,里面包含着类的数据和方法
类变量:在类中直接定义的变量,既可以通过类调用也可以通过实例调用(所有实例共用的属性)
实例变量:在构造函数中初始化的变量,作用域为实例本身
class Person:
nation = "China" #类变量
def __init__(self,name):
self.name = name #实例变量
print(Person.nation) #通过类调用类变量
p1 = Person("Joe")
print(p1.nation) #通过实例调用类变量
p1.nation = "Japan" #相当于创建了与类变量nation同名的实例变量
print(Person.nation) #此时还是China
print(p1.nation) #实际上调用的是nation实例变量
实例无法修改类变量,类变量只能通过类修改 (实例变量与类变量同名时,调用的优先级为先查找实例变量后查找类变量)
构造函数:在类实例化时进行初始化变量
析构函数:在实例释放、销毁的时候执行,通常用于执行一些收尾工作,如关闭一些数据库连接、打开的临时文件。
#类的封装
class Role:
n = 123 #类变量
def __init__(self,name,role,weapon,life_value=100,money=15000):
#构造函数
#实例化时进行初始化
self.name = name
self.role = role
self.weapon = weapon
self.life_value = life_value
self.money = money
def get_life_value(self):
return self.__life_value
def __del__(self):
#析构函数
#实例销毁的时候自动执行
print("%s 彻底死了"%self.name)
print(Role.n) #通过类调用类变量
r1 = Role('name','police','Ak') #实例化Role类,此时调用构造函数进行初始化
print(r1.n) #通过实例调用类变量
#------------------------------------------#
#程序结束后自动执行析构函数销毁实例
实现私有的方法:方法或者属性名称前加__(双下划线),这样实例就无法直接访问。
通常习惯上想访问私有属性时需要单独构造一个方法来返回私有属性
class Role:
def __init__(self,name,role,weapon,life_vaule=100,money=15000):
#构造函数
#实例化时进行初始化
self.name = name
self.role = role
self.weapon = weapon
self.__life_value = life_vaule #私有属性
self.money = money
def get_life_value(self):#通常构造一个函数来专门返回私有属性
return self.__life_value
def __del__(self):
#析构函数
#实例销毁的时候自动执行
print("%s 彻底死了"%self.name)
r1 = Role('name','police','Ak')
print(r1.get_life_value()) #打印私有属性
print(r1._Role__life_value) #也可以通过这种方式访问私有属性
指的是一个类(子类)从另外一个类(父类)获得了所有的成员,父类的成员可以在子类中使用
# 父类
class People:
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print(" %s is eating"%self.name)
def sleep(self):
print(" %s is sleeping"%self.name)
# 继承People的子类
class Man(People):
# 重构构造函数
def __init__(self,name,age,money):
#调用父类的构造函数的两种方法
#People.__init__(self,name,age)
super(Man,self).__init__(name,age) #方便简单(推荐)
self.money = money
def study(self):
print("%s is studying"%self.name)
def sleep(self): # 重构父类的方法
# 首先调用父类的方法
People.sleep(self)
# 对父类的方法进行补充
print("man is sleeping")
# 继承People的子类
class Woman(People):
#未定义构造方法,则实例化时直接调用父类的构造方法
def birth(self):
print("%s is birthing"%self.name)
m1 = Man("Joe",16,2000)
m1.sleep()
m1.eat()
w1 = Woman("Susan",22)
w1.birth()
如上,重构父类的构造函数时候有两种方法,一种是父类名称直接调用构造函数即ParentName.__init__(parameter),另一种是借助super()函数(推荐使用)
一个类可以同时继承好几个类,这就是多继承
对于PY3 经典类与新式类都是按照广度优先顺序来继承的
多态的作用是实现接口重用,即一种接口多种实现
Python虽然不支持多态但可以间接实现
class Animal:
def talk(self):
pass
@classmethod #静态方法
def say(cls,obj):
obj.talk()
class Cat(Animal):
def talk(self):
print("miao")
class Dog(Animal):
def talk(self):
print("wolf")
d = Dog()
c = Cat()
#通过Animal.say()接口了不同的实现
Animal.say(d)
Animal.say(c)
静态方法: 只是名义上归类管理,实际上在静态方法里访问不了类与实例中的的任何属性
class Dog(object):
def __init__(self,name):
self.name = name
# 静态方法,实际上和类没什么关系了
@staticmethod
def eat(self):
print("%s is eating %s"%(self.name,'dd'))
d = Dog("Jack")
Dog.eat(d)
#d.eat(d)
类方法: 只能访问类变量,不能访问实例变量
# 类方法
class Dog(object):
name = "Susan"
def __init__(self,name):
self.name = name
# 类方法
@classmethod
def eat(self):
print("%s is eating %s"%(self.name,'food'))
d = Dog("Jack")
Dog.eat() #打印的是Susan is eating food
#d.eat()
属性方法: 把一个方法变成一个静态属性
# 属性方法
class Dog(object):
def __init__(self,name):
self.name = name
self.__food = None
# 属性方法
@property
def eat(self):
print("%s is eating %s"%(self.name,self.__food))
@eat.setter #通过这样可以给eat属性赋值
def eat(self,food):
print("set to food:",food)
self.__food = food
@eat.deleter #通过这样可以删除eat属性
def eat(self):
del self.__food
print("删除成功")
d = Dog("Jack")
d.eat
d.eat = "baozi"
d.eat
del d.eat
反射:通过字符串映射或修改程序运行时的状态、属性、方法
有四种方法:
hasattr(obj,name_str):判断obj对象里是否与对应的name_str字符串的方法(属性)
getattr(obj,name_str):根据字符串去获取obj对象里的对应的方法(属性)的内存地址
setattr(obj,'y',z) : equivalant to 'x.y=z'
delattr(obj,name_str):删除Obj对象里的name_str方法(属性)
def bulk(self):
print("%s is bulking"%self.name)
class Dog(object):
def __init__(self,name):
self.name = name
def eat(self):
print("%s is eating"%self.name)
d = Dog("Jack")
choice = input(">>:").strip()
#判断是否还有相应的方法或者属性名称
if hasattr(d,choice):
#动态获取方法(若choice == food)
# func = getattr(d, choice)
# func()
#动态修改属性(若choice == name)
# setattr(d,choice,"Joe")
# print(d.name)
#动态删除属性
delattr(d,choice)
print(hasattr(d,choice))
else:
# 动态添加方法
# setattr(d,choice,bulk) #d.choice = bulk
# getattr(d,choice)(d)
#动态添加属性
setattr(d,choice,22)
print(getattr(d,choice))