一.函数式编程和面向对象编程区别
- 函数: 是将某些功能代码封装到函数中,不用重复编写,直接调用函数即可
- 面向对象: 是对函数分类和封装
def email(em,text): """ 发送邮件 :param em: :param text: :return: """ print(em,text)def msg(tel,text): """ 发送短信 :param tel: :param text: :return: """ print(tel,text)def wechat(num,text): """ 发送微信 :param num: :param text: :return: """ print(num,text)# 编写功能:用户购买商品,然后给商家发送提醒if 1 ==1: msg('13522289159','xxx购买了某个商品') email('592888935@qq.com','xxx购买了某个商品') wechat('xxxxxxx','xxx购买了某个商品')
class Message: def email(self,em,text): """ 发送邮件 :param em: :param text: :return: """ print(em, text) def msg(self,tel, text): """ 发送短信 :param tel: :param text: :return: """ print(tel, text) def wechat(self,num, text): """ 发送微信 :param num: :param text: :return: """ print(num, text) # 编写功能:用户购买商品,然后给商家发送提醒obj= Message()obj.msg('13522289159', 'xxx购买了某个商品')obj.email('592888935@qq.com', 'xxx购买了某个商品')obj.wechat('xxxxxxx', 'xxx购买了某个商品')
对比: 函数: 定义简单/调用简单 面向对象: 定义复杂/调用复杂 好处:归类/将某些类似的方法(函数)写在一起 总结: 函数式编程可以会比面向对象编程好 python支持两种编程方式
二.类与对象
面向对象编程核心二字即:'对象' 可以把类看做是一个包,包里可以包含多个函数,每个函数实现一个功能 对象则是根据包创建的一个实例,通过实例可以调用包里的函数
定义:class Foo: # 定义了一个类,Foo为类名 def func(): # 在类中编写了一个方法(单独称为函数,放到类中一般都被称为方法) pass调用:obj = Foo() # 创建了一个对象/实例化一个对象obj.func() # 通过对象调用类中的方法
class 是关键字,表示你将要创建一个类
创建对象即类名称加括号
提示: 类名定义的时候第一个字母大写,或每个单词的首字母大写(潜规则,可以看出你是不是个老司机)
练习题:
class Account: def login(self): user = input('请输入用户名:') pwd = input('请输入密码:') if user == 'alex' and pwd == 'SB': # SB即:烧饼 print('登录成功') else: print('登录失败')obj = Account()obj.login()
三.三大特性
三大特性:封装/继承/多态 - 封装(顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容) 将相关功能封装到一个类中
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 obj1 = Person('侯明巍',18,'男') obj2 = Person('房文磊',16,'女')
self 是一个形式参数,当执行 obj1 = Person('侯明巍',18,'男' ) 时,self 等于 obj1
当执行 obj2 = Person('房文磊',16,'女' ) 时,self 等于 obj2
所以,内容其实被封装到了对象 obj1 和 obj2 中,每个对象中都有 name 和 age 及 gender 属性,在内存分别开辟两个空间来保存。
"""完成以下功能: 老狗/20岁/男/上山去砍柴 老狗/20岁/男/开车去东北 老狗/20岁/男/喜欢大宝剑"""class LaoLi: def __init__(self,name,age,gender): # 特殊的方法,如果 类名(),则该方法会被自动执行 (构造方法) self.name = name self.age = age self.gender = gender def kc(self): data = "%s,%s,今年%s,喜欢上山去砍材" % (self.name, self.gender, self.age) print(data) def db(self): data = "%s,%s,今年%s,喜欢开车去东北" % (self.name, self.gender, self.age) print(data) def bj(self): data = "%s,%s,今年%s,喜欢去做大保健" % (self.name, self.gender, self.age) print(data)obj = LaoLi('老狗',20,'男')obj.kc()obj.db()obj.bj()
- 继承(面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容) - 单继承
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() 原则: 先在自己的类中找,找不到去父类找
站的角度不同,对待父类和子类的定义也不同,子类也有可能是别的类的父类 - 多继承
class Base1: def show(self): print('Base1.show')class Base2: def show(self): print('Base2.show')class Foo(Base1,Base2): passobj = Foo()obj.show()# 左边比右边更亲
总结: 1. 继承编写 2. python支持多继承 3.为什么要有继承: 提高代码的重用性 - 多态(多种形态和多种状态) python原生支持多态,所有没有特殊性 其Python崇尚“鸭子类型”
class F1: passclass S1(F1): def show(self): print 'S1.show'class S2(F1): def show(self): print 'S2.show'def Func(args): print args.show()s1_obj = S1()Func(s1_obj) s2_obj = S2()Func(s2_obj)
由于python函数在传参时没无需指定类型,args可以是多种类型,只要其中有seed方法即可 总结: 以上对面向对象知识总结 - 面相对象是一种编程方式,此编程方式的实现是基于对'类'和'对象'的使用 - 类是一个包,包中包装了多个'函数'供使用 - 对象,根据类创建的实例(即:对象),实例用于调用被包装的类中的函数 - 面向对象的三大特性: 封装/继承/多态 - 封装 归类,将函数放置到一个类中 打包,将数据打包放到一个对象中 - 继承 提高代码的重用性
四.类的成员
成员共分为三类: 1.变量 2.方法 3.属性 1.变量 实例变量(字段) - 公有实例变量(公有字段) - 私有实例变量(私有字段) 类变量(静态字段) - 公有类变量(公有静态字段) - 私有类变量(私有静态字段)
class Foo: # 类变量(静态字段) country = '中国' # 私有类变量 __secret = '贪污受贿'
def __init__(self,name,age): # 实例变量(字段) self.name = name # 私有实例变量 __self.age = age def func(self): pass
什么时候用类变量? 当所有对象中有共同的字段时且要改都改要删都删的时候,可以将实例变量(字段)提取到类变量(静态字段)
私有变量在函数外部是无法访问的
class Foo: def __init__(self,name): # 私有实例变量(私有字段) self.__name = name # 在变量前边加 '__' self.age = 26 def func(self): print(self.__name)obj = Foo('侯明巍')# print(obj.__name) # 无法访问print(obj.age)obj.func() # 可以让内部的func函数帮助执行内部私有的__name
class Foo: __country = '中国' def __init__(self): pass def func(self): # 内部调用 print(self.__country) print(Foo.__country) # 推荐使用类调用obj = Foo()obj.func()# 外部无法调用内部私有类变量# print(Foo.__country) # 外部无法调用
############ 无法访问class Baer(object): __secret = '贪污受贿'class Foo(Baer): def func(self): print(self.__secret) print(Foo.__secret)obj = Foo()obj.func()############ 可以访问class Baer(object): __secret = '贪污受贿' def func1(self): print(Baer.__secret)class Foo(Baer): def func2(self): print(self.__secret) print(Foo.__secret)obj = Foo()obj.func1()
2.方法 1.实例方法 公有实例方法 私有实例方法 2.静态方法 公有静态方法 私有静态方法 3.类方法 公有类方法 私有类方法
class Foo(object): def __init__(self,name): self.name = name # 实例方法 def func1(self): print('实例方法') # 私有实例方法 def __display1(self) print('私有方法') # 静态方法 @staticmethod def func2(): print('静态方法') # 私有静态方法 def __display2(): print('私有静态方法') # 类的方法. cls是类 @classmethod def func3(cls): print(类方法) # 私有类方法 @ classmethod def __display(cls) print('私有类方法')
静态方法总结: 1.编写时: - 方法上方写 @staticmethod - 方法参数(self)可有可无 2.调用时: - 类.方法名() # 推荐 - 对象.方法名() 3.什么时候写静态方法 - 无需使用对象中封装的值的时候
类方法总结: 1.定义时: - 方法上方写 @classmethod - 方法的参数:至少有一个cls的参数 2.执行时: - 类名.方法名() # 默认会把当前类传到参数中 3.什么时候用类方法 - 如果在方法中会使用到当前类,那么久可以使用类方
静态方法/类方法和实例方法的区别?
1.定义: 1.实例方法上方什么也不加 2.静态方法上方加 @staticmethod 3.类方法上方加 @classmethod 2.执行: 1.实例方法是先实例化,再通过对象.方法名 2.静态方法是通过类.方法名 3.类方法是通过类.方法名
3.属性(通过方法改造出来的) 公有属性 私有属性
class Foo(object): def __init__(self): pass # 属性 @property def start(self): return "hell word,I's'赛利亚" # 私有属性 @property def __end(self): return '你好啊,我是赛利亚'
属性总结: 1.编写时 - 方法上方写 @property - 方法参数: 只有一个self 2.调用时: 无需加括号,直接 对象.方法 3.应用场景: 对于简单的方法,当无需传参且有返回值时,可以使用 @property