绑定方法
1.绑定给对象的
2.绑定给类的
绑定给对象
class Student():
country = 'CHINA'
def __init__(self,name,age):
self.name = name
self.age = age
def tell_info(self):
print('%s-%s'% (self.name,self.age))
obj = Student('egon',90)
obj.tell_info()
绑定给类
class Mysql():
country = 'CHINA'
def __init__(self,ip,port):
self.ip = ip
self.port = port
# 类方法是绑定给类的,类来调用,把类名当做第一个参数传递
# 用classmethod装饰器将函数绑定给类
@classmethod
def from_config(cls):
obj = cls(settings.IP,settings.PORT)
return obj
Mysql.from_config()
# cls相当于self,cls是传递类名,self是传递对象名
非绑定方法
# 不绑定给对象也不绑定给类,调用方法参数该怎么传就怎么传
class Mysql():
country = 'CHINA'
def __init__(self,ip,port):
self.ip = ip
self.port = port
@staticmethod # 静态方法
def create_id():
import uuid
print(uuid.uuid4())
obj.create_id()
Mysql.craete_id()
隐藏属性
如何隐藏属性
# 在需要的对象名前加__,即可隐藏属性
class People():
__country = 'CHINA'
# 此时__country在类名称空间内的名称是_People__country,用以隐藏
def __init__(self,name,age):
self.__name = name
self.age = age
# 此时__name在对象名称空间内的名称是_People__name,用以隐藏
def __func(self):
print('hello world')
# 此时__func在类名称空间内的名称是_People__func,用以隐藏
def test(self):
return '国家:%s'% self.__country
def set_country(self,v):
if type(v) is not str:
print('country必须是str类型')
return
# 如果想访问类中的隐藏属性,在类中开放对外访问的接口,可以更好的对外部做限制
self.__country = v
def del_country(self):
print('不能删除')
obj = People('ly',18)
print(People._People__country)
# 隐藏属性只是在类定义阶段,在语法上的变形,并非真正的隐藏起来了,用变形后的名称也可以对其进行操作
print(obj.test) # CHINA
# 该隐藏对外不对内,内部的代码可以直接用__country,实际指向的就是_Peoplr__country
# 变形操作只在类定义阶段,之后的所有属性或者方法,都不会变形了
obj.__x = 'x'
# 此时__x在对象名称空间内的名称还是__x
为什么要隐藏属性
class ATM:
def __card(self): #插卡
print('插卡')
def __auth(self): #身份认证
print('用户认证')
def __input(self): #输入金额
print('输入取款金额')
def __print_bill(self): #打印小票
print('打印账单')
def __take_money(self): #取钱
print('取款')
def withdraw(self): #取款功能
self.__card()
self.__auth()
self.__input()
self.__print_bill()
self.__take_money()
obj=ATM()
obj.withdraw()
例如ATM程序的取款功能,功能需要由很多的其他功能组成,但是用户只需要开发取款这个功能即可,其他的功能就需要进行隐藏
扩展
python3中统一了类与类型的概念
l = [1,2,3] # l = list([1,2,3])
l.append(4) # list.append(l,4)
property装饰器
# 将一个功能伪装成一个数据属性
class People():
def __init__(self,name,age):
self.__name = name
self.age = age
@property
def name(self):
return self.__name
obj = People('ly',18)
print(obj.name)
# 此时name后不需要加括号,因为name的返回值被伪装成了一个数据属性
setter装饰器
例如:
class People():
def __init__(self,name,age):
self.__name = name
self.age = age
@property
def name(self):
return self.__name
# 此时需要添加一个类似平时的操作的修改名字操作
# 类似:obj.name = 'x',正常操作是obj.set_name('x')
@name.setter
def set_name(self,v):
if type(v) is not str:
print('必须是str类型')
return
self.__name = v
# name是搭载了property装饰器的函数的函数名,如果函数名不是name则修改为正确函数名
继承
面向对象的三大特征
1.封装
2.继承
3.多态
什么是继承
继承就是一种新建类的方式
新建的类称为子类或者叫派生类
被继承的类称为父类或者叫基类
子类可以遗传父类的属性
为什么用继承
类解决对象与对象之间的代码冗余问题
继承解决类与类之间的代码冗余的问题
如何用继承
python支持多继承
class Parent1:
pass
class Parent2:
pass
class Sub1(Parent1):
pass
class Sub2(Parent1,Parent2):
pass
print(Parent1.__bases__) # (<class 'object'>,)
# 查看其父类
print(Sub2.__bases__) # (<class '__main__.Parent1'>, <class '__main__.Parent2'>)
经典类:没继承object类以及该类的子子孙孙类
新式类:继承了object类以及该类的子子孙孙类
在python2中区分经典类和新式类
在python3中都是新式类
继承案例
class People():
school = 'SH'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
class Student(People):
def __init__(self,name,age,gender,course=None):
if course is None:
self.courses = []
People.__init__(self,name,age,gender)
def choose_course(self,course):
self.courses.append(course)
print(f'{self.name}选课成功{self.courses}')
class Teacher(People):
def __init__(self,name,age,gender,level):
self.level = level
People.__init__(self,name,age,gender)
def score(self,stu_obj,num):
stu_obj.num = num
print(f'{self.name}老师给{stu_obj.name}打了{num}分')
stu1 = Student('egon',18,'male')
tch1 = Teacher('milu',20,'male',100)
知识点
子类如何使用父类的属性:
1.指名道姓,例如上文的
People.__init__(self,name,age,gender)
# 不使用继承也可以使用此方法
2.super() 严格依赖继承