day20
回顾
类的三大特性
封装、继承、多态
1.类成员
类
类变量
绑定方法
类方法
静态方法
属性
实例(对象)
实例变量
1.1 实例变量
1.2 类变量
1.2.1 定义
写在类的下一级,与方法同一级。
1.2.2 访问
类.类变量名称
对象.类变量名称
1.2.3 面试题
class Base:
x = 1
obj = Base()
print(obj.x) # 先去对象中找,没有再去类中找。
obj.y = 123 # 在对象中添加了一个y=123的变量。
print(obj.y) # 123
obj.x = 123
print(obj.x) # 123
print(Base.x) # 1
class Parent:
x = 1
class Child1(Parent):
pass
class Child2(Parent):
pass
print(Parent.x,Child1.x,Child2.x) # 1 1 1
Child1.x = 2
print(Parent.x,Child1.x,Child2.x) # 1 2 1
Child2.x = 3
print(Parent.x,Child1.x,Child2.x) # 1 2 3
1.2.4 总结
总结:找变量优先找自己,自己没有找 类 或 基类;修改或赋值只能在自己的内部设置。
1.3 方法(绑定方法/普通方法)
1.3.1 定义
至少有一个self参数
1.3.2 执行
先创建对象,再由对象.方法()
class Foo:
def func(self,a,b):
print(a,b)
obj = Foo()
obj.func(1,2) # 浪费资源 此处并未调用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) # 123 1 2
1.4 静态方法
1.4.1 定义
@staticmethod装饰器
参数无限制
1.4.2 执行
类.静态方法名()
对象.静态方法名()
class Foo:
def __init__(self):
self.name = 123
def func(self, a, b):
print(self.name, a, b)
1.5 类方法
1.5.1 定义
@classmethod装饰器
至少有cls参数,当前类
1.5.2 执行
类.类方法()
对象.类方法()
class Foo:
def __init__(self):
self.name = 123
def func(self, a, b):
print(self.name, a, b)
1.5.3 面试题
# 问题: @classmethod和@staticmethod的区别?
"""
一个是类方法一个静态方法。
定义:
类方法:用@classmethod做装饰器且至少有一个cls参数。
静态方法:用staticmethod做装饰器且参数无限制。
调用:
类.方法直接调用。
对象.方法也可以调用。
"""
1.6 属性
1.6.1 定义
@property装饰器
只有一个self参数
1.6.2 执行
对象.方法 无需添加括号
class Foo:
# 属性的应用
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
2.成员修饰符
1.公有 所有地方都能访问到
2.私有 只有自己可以访问到
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
class Foo:
def __fun(self):
print('msg')
def show(self):
self.__fun()
obj = Foo()
# obj.__fun() # 报错 无法获取
obj.show() # 可以通过类内部另外的方法调取
3.强制访问私有成员
# 强制访问私有成员
class Foo:
def __init__(self,name):
self.__x = name
obj = Foo('alex')
print(obj._Foo__x) # 强制访问私有实例变量
3.补充 类的嵌套
class Foo:
def __init__(self,num):
self.num = num
cls_list = []
for i in range(10):
cls_list.append(Foo) # [Foo,Foo,Foo,Foo,Foo,Foo,Foo,Foo,Foo,Foo]
for i in range(len(cls_list)):
obj = cls_list[i](i) # [Foo(0),Foo(1),Foo(2),Foo(3),Foo(4),Foo(5),Foo(6),Foo(7),Foo(8),Foo(9)]
print(obj.num) # 0 1 2 3 4 5 6 7 8 9
class Foo:
def __init__(self,num):
self.num = num
B = Foo # 别名
obj = B('alex') # alex
class Foo:
def f1(self):
print('f1')
def f2(self):
print('f2')
obj = Foo()
v = [ obj.f1,obj.f2 ]
for item in v:
item() # f1 f2
class Foo:
def f1(self):
print('f1')
def f2(self):
print('f2')
def f3(self):
v = [self.f1 , self.f2 ]
for item in v:
item()
obj = Foo()
obj.f3() # f1 f2
class Account:
def login(self):
pass
def register(self):
pass
def run(self):
info = {'1':self.register, '2':self.login }
choice = input('请选择:')
method = info.get(choice)
method()
class Foo:
pass
class Foo(object):
pass
# 在python3中这俩的写法是一样,因为所有的类默认都会继承object类,全部都是新式类。
# 如果在python2中这样定义,则称其为:经典类
class Foo:
pass
# 如果在python2中这样定义,则称其为:新式类
class Foo(object):
pass
class Base(object):
pass
class Bar(Base):
pass
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
# ############################################
v = [11,22,33,{'name':'山海','addr':'浦东'}]
v[0]
v[3]['name']