s21day20 python笔记
一、内容回顾
- 面向对象的三大特性
- 封装
- 函数封装到类
- 数据封装到对象
- 继承
- 多态
- 封装
二、成员
2.1 类成员
类变量(静态字段)
- 定义:写在类的下一级,和方法同一级
- 访问:
- 类.类变量名()
- 对象.类变量名()
- 注意:如果对象中也有同名变量,则对象.类变量名()使用对象自己中的变量
# 面试题 class Base: x = 1 obj = Base() print(obj.x) # 先去对象中找,没有再去类中找 obj.y = 123 # 在对象中添加了一个y=123的变量 obj.x = 123 # 在对象中添加了一个X=123的变量,无法修改类变量 Base.x = 666 # 修改类变量,x = 666
- 总结:
- 找变量优先找自己,自己没有找 类 或 基类
- 修改或赋值只能在自己的内部设置
绑定方法(普通方法)
- 定义:至少有一个self参数
- 执行:先实例化对象,对象.绑定方法名()
class Foo: def __init__(self): self.name = 123 def func(self, a, b): print(self.name, a, b) obj = Foo() obj.func(1, 2)
静态方法
- 定义:
- @staticmethod装饰器
- 参数无限制
- 执行:
- 类.静态方法名()【推荐】
- 对象.静态方法名()【不推荐,容易混淆】
class Foo: def __init__(self): self.name = 123 @staticmethod def f1(): print(123) obj = Foo() Foo.f1() obj.f1() # 不推荐
- 定义:
类方法
- 定义:
- @classmothod装饰器
- 至少有cls参数(cls是当前类)
- 执行:
- 类.类方法名()【推荐】
- 对象.类方法名()【不推荐,容易混淆】
class Foo: def __init__(self): self.name = 123 @classmethod def f2(cls,a,b): print('cls是当前类',cls) print(a,b) obj = Foo() Foo.f2(1,2) obj.f2(1,2) # 不推荐
- 面试题(笔试)
- 问: @classmethod和@staticmethod的区别?
- 答:一个是类方法,一个静态方法
定义:
类方法:用@classmethod做装饰器且至少有一个cls参数
静态方法:用staticmethod做装饰器且参数无限制
调用:
类.方法直接调用,对象.方法也可以调用
- 定义:
属性
- 定义:
- @property
- 只能有一个self参数
- 执行:
- 对象.方法名
- 后面不用加括号
class Foo: @property def func(self): print(123) return 666 obj = Foo() result = obj.func print(result)
- 应用:
# 属性的应用 class Page: def __init__(self, total_count, current_page, per_page_count=10): self.total_count = total_count self.per_page_count = per_page_count self.current_page = current_page @property def start_index(self): return (self.current_page - 1) * self.per_page_count @property def end_index(self): return self.current_page * self.per_page_count USER_LIST = [] for i in range(321): USER_LIST.append('alex-%s' % (i,)) # 请实现分页展示: current_page = int(input('请输入要查看的页码:')) p = Page(321, current_page) data_list = USER_LIST[p.start_index:p.end_index] for item in data_list: print(item)
- 定义:
2.2 实例(对象)成员
实例成员:实例变量
实例(对象)之间的嵌套
示例:
class School(object): def __init__(self,title,addr): self.title = title self.address = addr class ClassRoom(object): def __init__(self,name,school_object): self.name = name self.school = school_object s1 = School('北京','沙河') s2 = School('上海','浦东') s3 = School('深圳','南山') c1 = ClassRoom('全栈21期',s1) c1.name c1.school.title c1.school.address
2.3 成员修饰符
公有,所有地方都能访问到
私有,只有自己可以访问到,修饰符:双下划线_ _
# 示例一: class Foo: def __init__(self, name): self.__name = name def func(self): print(self.__name) obj = Foo('alex') # print(obj.__name),报错,无法访问 obj.func() # 示例二: class Foo: __x = 1 @staticmethod def func(): print(Foo.__x) # print(Foo.__x),报错,无法访问 Foo.func() # 示例三: class Foo: def __fun(self): print('msg') def show(self): self.__fun() obj = Foo() # obj.__fun(),报错,无法访问 obj.show()
强制访问私有,中间加上_类名
class Foo: def __init__(self,name): self.__x = name obj = Foo('alex') print(obj._Foo__x) # 强制访问私有实例变量