一、类与对象:
1、特性:类是对象的类型,对象是类的实例化。类与类之间可以嵌套继承。
2、类的定义:
属性: 类属性和对象属性
方法: 初始化方法,普通方法,静态方法,类方法
理解:面向对象的函数式设计:
#面向对象
class Person:
county = 'China' # 类属性 类和所有对象都能够调用,用 . 的方式。
def __init__(self,name,age,sex): # 构造函数(初始化函数)
self.name = name # 第一个name是属性(对象字典的key),第二个name是形参(具体对象的values)
self.age = age # 实例变量
self.sex = sex
def func(self,color='黄皮肤'): #
print('%10s 年龄 %d 岁,性别 %s %s' %(self.name,self.age,self.sex,color))
# 得到对象需要类的实例化,实例化时需要传递对象的具体特征,必须是初始化函数定义过的。
# Person.func() 不能用类名调用参数
people_me = Person('刘',22,'男性') # 类的 实例化
people_me.func() # 对象调用类的方法。
people_me.func(color= '白皮肤') # 实例化没有传入属性,不可用self.调用。
# 类属性
print(Person.county)
print(people_me.county)
二、 类属性(类变量):
类属性 用类名.属性名来调用,对象属性在类外面用对象名.属性名来调用 ,在类里面用self.属性名来调用。
1、类属性:类变量
(1) 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为
实例变量使用。
(2)类属性的增删改查:
getattr、setattr、hasattr、delattr :这些方法是系统方法,同样适用与对象属性。
①类属性的查看:类名.属性名、对象.属性名、getattr(类名,属性名)
class Person:
county = 'China'
def __init__(self,):
pass
people1 = Person()
print(Person.county) 通过类名
print(getattr(Person,"county")) 通过getattr
print(people1.county) 通过对象
print(getattr(people1,"county")
结果:
China
China
China
China
②类属性的增加与修改:setattr
class Person:
def __init__(self, newName, newAge):
self.name = newName
self.age = newAge
Person.county = 'China' 直接通过 类名 添加类属性
还可以:
setattr(Person,'county','China') 通过 getattr 类名
③类属性的删除:delattr
class Person:
county = 'China'
def __init__(self, newName, newAge):
self.name = newName
self.age = newAge
delattr(Person,'county') delattr 类名
④类属性是否存在:hasattr
class Person:
county = 'China'
def __init__(self, newName, newAge):
self.name = newName
self.age = newAge
hasattr(Person.county) >>>>>> bool值
2、对象属性:
(1)对象属性的理解:
类实例化对象的属性。
(2)对象属性的增删改查:
与类属性相似,将 类名 换为 对象名:
对象属性不像类属性,对象属性的更改只对这个对象起作用,其他类对象不能获取。
class Person:
county = 'China'
def __init__(self, newName, newAge):
self.name = newName
self.age = newAge
people1 = Person('张三','20')
获取对象属性:
1、print(getattr(people1,'name'))
2、print(people1.name)
添加或修改对象属性:没有值时会自动添加,类似字典的 setdefault 方法。
1、setattr(people1,'addr','北京')
print(people1.name)
2、people1.addr = '北京'
print(people1.name)
删除对象属性:delattr
判断是否存在对象属性:hasattr
三、python内置类属性:
1、内置类属性的介绍:
内置类属性
print(mc.__dict__) {'restaurant_name': '麦当劳', 'cuisine_type': '快餐'}结果是 对象属性 组成的字典
print(Restaurant.__dict__) 结果是 类和对象属性 组成的字典
print(Restaurant.__doc__)
print(mc.__doc__)
print(Restaurant.__name__) #Restaurant
__bases__ : 类的所有父类构成元素 (包含了以个由所有父类组成的元组)
print(Restaurant.__bases__) # 基类
模块导入时,__name__ 的用法
print(__name__) #__main__
if __name__=='__main__':
print('专有')
2、 __name__:
四、习题例题:
1、如何记录实例化次数:
如何查看实例化的次数?
class people():
num=0
def __init__(self):
self.name='杨幂'
people.num+=1
yangmi1=people()
yangmi2=people()
yangmi3=people()
print(people.num) # 3
2、实例:
1.餐馆:创建一个名为Restaurant的类,其方法__init__()设置两个属性:
restaurant_name 和 cuisine_type(烹饪)。
创建一个名为 describe_restaurant()方法和一个名为open_restaurant ()方法,
其中前者打印前述两项信息,而后者打印一条消息,指出餐馆正在营业。
根据这个类创建一个名为restaurant的实例,分别打印其两个属性,再调用前述两个方法。
三家餐馆:根据你为完成练习1而编写的类创建三个实例,并对每个实例调用方法 describe_restaurant()。
-------------------------------------------------------------------------------------------
3.就餐人数:在为完成练习1而编写的程序中,添加一个名为number_served的属性,并将其默认值设置为0。
打印有多少人在这家餐馆就餐过,然后修改这个值并再次打印它。
添加一个名为set_number_served()的方法,它让你能够设置平日就餐人数。
调用这个方法并向它传递一个值,然后再次打印这个值。
添加一个名为increment_number_served()的方法,它让你能够将就餐人数递增.
调用这个方法并向它传递一个这样的值:你认为这家餐馆每天可能接待的就餐人数
class Restaurant:
'''这是一个餐馆类: (用来干嘛干嘛)'''
def __init__(self,restaurant_name,cuisine_type,number_served=0):
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
self.number_served = number_served
def describe_restaurant(self):
print('餐馆的名字是%s,菜的类型是%s'%(self.restaurant_name,self.cuisine_type))
def open_restaurant(self):
print('正在营业')
def set_number_served(self,n):
self.number_served = n #setattr(obj,"key",value)
print('现在餐馆中就餐的人数是%d人'%self.number_served)
def increment_number_served(self,add_num):
self.number_served+=add_num
print('现在餐馆中就餐的人数是%d人'%self.number_served)
def reset_login_attempts(self):
self.number_served=0
print('人数清空')
五、继承与多态:
1、类继承的特性:
(1) 程序中当我们定义一个class的时候,可以从某个现有的class继承,新的class称之为子类(Subclass),而被继 承的 class称之为基类、父类或超类。子类继承了其父类的所有属性和方法(私有属性和方法除外),同时还可以定义自己的属性和方法。
(2)父类不能够访问子类。
2、子类继承方法顺序和方法重写(override):
① 子类继承的格式:
②子类继承顺序与方法重写:
class C():
def c(self):
print('c')
def a(self):
print('c2')
class A():
def a(self):
print('a')
def c(self):
print('a2')
class B(C,A): #继承的类名 排在左边的优先显示
def b(self):
print('b')
def a(self): #override 方法重写,子类方法覆盖父类方法。
print('b2')
ob = B()
ob.b()
ob.c()
ob.a()
2、子类添加属性的方法,super():
(1)实例:
1.餐馆:创建一个名为Restaurant的类,其方法__init__()设置两个属性:
restaurant_name 和 cuisine_type(烹饪)。
创建一个名为 describe_restaurant()方法和一个名为open_restaurant ()方法,
其中前者打印前述两项信息,而后者打印一条消息,指出餐馆正在营业。
根据这个类创建一个名为restaurant的实例,分别打印其两个属性,再调用前述两个方法。
三家餐馆:根据你为完成练习1而编写的类创建三个实例,并对每个实例调用方法 describe_restaurant()。
-------------------------------------------------------------------------------------------
3.就餐人数:在为完成练习1而编写的程序中,添加一个名为number_served的属性,并将其默认值设置为0。
打印有多少人在这家餐馆就餐过,然后修改这个值并再次打印它。
添加一个名为set_number_served()的方法,它让你能够设置平日就餐人数。
调用这个方法并向它传递一个值,然后再次打印这个值。
添加一个名为increment_number_served()的方法,它让你能够将就餐人数递增.
调用这个方法并向它传递一个这样的值:你认为这家餐馆每天可能接待的就餐人数
class Restaurant:
'''这是一个餐馆类: (用来干嘛干嘛)'''
def __init__(self,restaurant_name,cuisine_type,number_served=0):
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
self.number_served = number_served
def describe_restaurant(self):
print('餐馆的名字是%s,菜的类型是%s'%(self.restaurant_name,self.cuisine_type))
def open_restaurant(self):
print('正在营业')
def set_number_served(self,n):
self.number_served = n #setattr(obj,"key",value)
print('现在餐馆中就餐的人数是%d人'%self.number_served)
def increment_number_served(self,add_num):
self.number_served+=add_num
print('现在餐馆中就餐的人数是%d人'%self.number_served)
def reset_login_attempts(self):
self.number_served=0
print('人数清空')
冰淇淋小店重写 super()添加对象属性 flavors
class IceCreamStand(Restaurant):
def __init__(self,restaurant_name, cuisine_type,flavors,number_served=1): # flavors是添加的子类属性。
super().__init__(restaurant_name, cuisine_type, number_served=1)
self.flavors=flavors # 添加子类属性
def get_info(self):
#重写父类
# def describe_restaurant(self):
print('这家冰激凌小店的名字是%s,它的烹饪类型是%s,冰激凌口味包含%s'%(self.restaurant_name,self.cuisine_type,self.flavors))
if __name__ == '__main__':
Ice1=IceCreamStand('星吧乐','手工制作',['辣的','咸的','甜的','酸的','苦de']) #传参数时,父类与子类新加的对象属性都要传。
# Ice1.get_info()
#父类重写
Ice1.describe_restaurant()
Ice1.get_info()
3、子类与父类 类型判断(两个系统函数isinstance()、type()):
class A:
def func1(self):
pass
class B(A):
def func2(self):
pass
print(isinstance(B(),A)) # 子类父类 类型相同
print(type(B()) == type(A)) # 判断子类父类 类型不同
结果:
True
False
六、访问限制:
1、私有属性(类属性和对象属性)的特性:
私有类属性
私有对象属性:
为了保护属性不被随意修改和访问,可以将属性定义为私有属性。
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例变量名如果以__开头, 就变成了一个私有变量(private),只有内部可以访问,外部不能访问. 这样就确保了外部代码不能随意修改对象内 部的状态,这样通过访问限制的保护,代码更加健壮,且可以对参数做检查(if elif),避免传入无效的参数
2、代码:
class Person:
__county = 'China' # 私有类属性
def __init__(self, newName, newAge):
self.__name = newName # 私有对象属性
self.age = newAge
def func(self): # 普通方法
print(self.__name)
def __func(self): # 私有方法
pass
print(Person.__county) # 报错,无法访问
people1 = Person('私有属性','正常属性')
print(people1.__name) # 报错,无法访问
print(people1.age) # 正常属性
如果赋值的话相当于添加了新__name,并没有获得私有对象属性 __name.
people1.__name = '赋值'
print(people1.__name) 结果 赋值
people1.func() 结果 私有属性 ,即内部还是调用原有的私有属性 __name。
强行访问 对象名._类名__属性名
print(people1._Person__name) # 私有属性
七、类方法与静态方法:
1、普通方法:
2、静态方法:
1
3、类方法:
2
4、代码: