一,编写与执行
"""编写类和执行类中方法的流程。 """ #编写类 # class 类名: # def 函数名(self,参数): #编写一个方法 # pass # obj = 类名 #实质化一个对象 # obj.函数名(参数) #通过对象调用一个方法
二,面向对象的三大特性:封装/继承/多态
封装: 将相关功能封装到一个类中: class Message: def email(self):pass def msg(self):pass def wechat(self):pass 将数据封装到一个对象中: class Person: def __init__(self,name,age,gender): self.name = name self.age = age self.gender = gender obj = Person('孙福来',18,'女')
继承: class SuperBase: def f3(self): print('f3') class Base(SuperBase): # 父类,基类 def f2(self): print('f2') class Foo(Base): # 子类,派生类 def f1(self): print('f1') obj = Foo() obj.f1() obj.f2() obj.f3() # 原则:现在自己类中找,么有就去父类 总结: 1. 继承编写 class Foo(父类): pass 2. 支持多继承(先找左/再找右) 3. 为什么要有多继承? 提供代码重用性 多态: 多种形态或多种状态 鸭子模型,只要可以嘎嘎叫就是鸭子. #Python # 由于python原生支持多态,所以没有特殊性. """ class Foo1: def f1(self): pass class Foo2: def f1(self): pass class Foo3: def f1(self): pass def func(arg): arg.f1() obj = Foo1() # obj= Foo2() obj = Foo3() func(obj) """ #java class Son(list): pass class Son1(list): pass # 以后传参时,arg可以是:list类的对象/list任何子类的对象 public void func(list arg){ print(arg) } # obj = list() # obj = Son() obj = Son1() func(obj)
三,面向对象中的self指什么
self 是形式参数,指调用类时创建的对象
练习:
'''定义一个类,计算周长和面积的方法(圆的半径通过参数传递到构造⽅方法)。''' import math class Compute: def __init__(self,r): self.r = int(r) def perimeter(self): return 2*math.pi*self.r def area(self): return math.pi*self.r**2 obj = Compute(3) print(obj.perimeter()) print(obj.area())
"""1. while循环提示⽤用户输入:用户名、密码、邮箱(正则满⾜邮箱格式) 2. 为每个⽤用户创建一个对象,并添加到列表中。 3. 当列表中添加了3个对象后,跳出循环并以此循环打印所有⽤用户的姓名和邮箱。如: 我叫zwq,邮箱是xxx@live.com 我叫breeze,邮箱是xxx@live.com""" import re user_list = [] while True: user = input("请输入用户名:") pwd = input("请输入密码:") email = input("请输入邮箱:") email_ret = re.search('[0-9a-zA-Z][w-.]+@[a-zA-Z0-9-]{2,5}.com',email) if email_ret: class User: def __init__(self, name, pwd, email): self.name = name self.pwd = pwd self.email = email obj = User(user, pwd, email) user_list.append(obj) if len(user_list) == 3: for i in user_list: print('我叫%s,邮箱是%s'%(i.name,i.email)) break else: print('邮箱格式不正确请重新输入')
class User: def __init__(self,name,pwd): self.name = name self.pwd = pwd class Account: def __init__(self): self.user_list = [] #用户列表,数据格式[User对象,User对象,User对象] def login(self): """用户登录,用户输入用户名和密码并去self.user_list中检查用户是否合法 :return: """ print("欢迎来到登录系统,请登录") n = 3 while n > 0: user_name = input('请输入用户名') user_pwd = input('请输入登录密码') for i in self.user_list: if user_name == i.name and user_pwd == i.pwd: print("欢迎登录") return else: n -= 1 print( '用户名或密码错误,请重新输入,还有%s次机会'%n) if n==0: print('请15分钟之后再试') def register(self): """用户注册,动态创建User对象,并添加到self.user_list中 :return: """ print("欢迎来到注册系统,请进行注册") user_name = input('请输入用户名') user_pwd = input('请输入注册密码') obj = User(user_name,user_pwd) self.user_list.append(obj) def run(self): """主程序,先进行两次用户注册,再进行用户登录(3次重试机会) :return: """ for i in range(2): self.register() self.login() if __name__ == '__main__': obj = Account() obj.run()
四,类的成员
成员共分为三类: 变量; 方法; 属性
1.变量:
- 实例变量(字段)
- 公有实例变量(字段)
- 私有实例变量(字段)
- 类变量(静态字段)
- 公有类变量(静态字段)
- 私有类变量(静态字段)
# 实例一: class Foo: # 类变量(静态字段) country = "中国" def __init__(self,name): # 实例变量(字段) self.name = name def func(self): pass obj1 = Foo('zwq') obj2 = Foo('breeze') Foo.country
类的子类(派生类)也不能调用其私有变量
#无法访问: class Base(object): __secret = "受贿" class Foo(Base): def func(self): print(self.__secret) print(Foo.__secret) obj = Foo() obj.func() #可以访问: class Base(object): __secret = "受贿" def zt(self): print(Base.__secret) class Foo(Base): def func(self): print(self.__secret) print(Foo.__secret) obj = Foo() obj.zt()
2.方法:
实例方法;静态方法;类方法
# 实例方法 class Foo(object): def __init__(self, name): self.name = name # 实例方法 def func(self): print(self.name) obj = Foo('..') obj.func() # 静态方法 class Foo(object): def __init__(self, name): self.name = name # 静态方法,如果方法无需使用对象中封装的值,那么就可以使用静态方法 @staticmethod def display(a1,a2): return a1 + a2 Foo.display(1,3) # 类方法 class Foo(object): # 类方法,cls是类 @classmethod def show(cls,x1,x2): print(cls,x1,x2) # 执行类方法 Foo.show(1,8)
3.属性
#示例: class Foo(object): def __init__(self): pass @property def start(self): return 1 @property def end(self): return 10 obj = Foo() print(obj.start) print(obj.end) """ 总结: 1. 编写时 - 方法上方写 @property - 方法参数:只有一个self 2. 调用时:无需加括号 对象.方法 3. 应用场景: 对于简单的方法,当无需传参且有返回值时,可以使用 @property """
五,类的组合(嵌套)
#面向对象: """ 创建三个学校且三个学校的设施内容等都是一致. """ class School(object): def __init__(self, name, address): self.name = name self.address = address def speech(self): print('讲课') obj1 = School('老男孩北京校区', '美丽富饶的沙河') obj2 = School('老男孩上海校区', '浦东新区') obj3 = School('老男孩深圳校区', '南山区') class Teacher(object): def __init__(self, name, age, salary): self.name = name self.age = age self.__salary = salary self.school = None t1 = Teacher('李杰', 19, 188888) t2 = Teacher('艳涛', 18, 60) t3 = Teacher('女神',16, 900000) # ############## 老师分配校区 t1.school = obj1 t2.school = obj1 t3.school = obj2 # #################################### # 查看t1老师,所在的校区名称/地址 print(t1.school.name) print(t1.school.address) print(t1.name) print(t1.age) t1.school.speech() #准则: 字段和方法的归类.
注意:类或对像可以作字典的键
六,特殊成员
class Foo(object): def __init__(self,a1,a2): self.a1 = a1 self.a2 = a2 def __call__(self, *args, **kwargs): print(11111,args,kwargs) return 123 def __getitem__(self, item): print(item) return 8 def __setitem__(self, key, value): print(key,value,111111111) def __delitem__(self, key): print(key) def __add__(self, other): return self.a1 + other.a2 def __enter__(self): print('1111') return 999 def __exit__(self, exc_type, exc_val, exc_tb): print('22222') # 1. 类名() 自动执行 __init__ # obj = Foo(1,2) # 2. 对象() 自动执行 __call__ # ret = obj(6,4,2,k1=456) # 3. 对象['xx'] 自动执行 __getitem__ # ret = obj['yu'] # print(ret) # 4. 对象['xx'] = 11 自动执行 __setitem__ # obj['k1'] = 123 # 5. del 对象[xx] 自动执行 __delitem__ # del obj['uuu'] # 6. 对象+对象 自动执行 __add__ # obj1 = Foo(1,2) # obj2 = Foo(88,99) # ret = obj2 + obj1 # print(ret) # 7. with 对象 自动执行 __enter__ / __exit__ # obj = Foo(1,2) # with obj as f: # print(f) # print('内部代码')