python的面向对象,今天说说这个概念。
一、类的分类
1、经典类与新式类
class Person: #经典类 pass class Person(object): #新式类 pass #类名首字母要大写 #在python3里面经典类和新式类没有任何区别
2、类的定义示例
class Person: #经典类 #构造函数就是类在实例化的时候执行的函数 def __init__(self, name): #构造函数 # self.name='xxxx' self.name = name self.nose = 2 #鼻子 #属性 self.face = 2 #脸 self.head = 10 #脑子 self.wing = 4 #翅膀 print('开始造人') def driver(self): print('老司机,开车非常稳') self.eat() #调用类里面的函数 def fly(self): print('%s 在飞...'%self.name) def eat(self): print('%s 吃火锅,吃小龙虾' %self.name) #类在用到的时候,首先必须实例化 # person1 = Person() #实例化,类名()就是实例化 # person1.eat() # person1.fly() # person1.eat() # print(person1.wing) # print(person1.nose) p1 = Person('demo') print(p1.nose) print(p1.name) p1.fly() p1.driver() # print(Person.wing) #AttributeError: type object 'Person' has no attribute 'wing'
3、类的执行顺序
类实例化 -> 构造函数-> 程序执行完->析构函数
二、面向对象与面向过程的区别
需求:
1、请求数据获取到
2、提取到商家编码
3、将商家编码进行2次md5,得到astr
4、再将请求数据进行一次urldecode,urlstr
5、将astr+urlstr
6、将结果md5
另,url编码:
from urllib import parse
url = 'http://www.baidu.com?query=python基础教程'
# print(parse.quote_plus(url)) #url编码
url_str = parse.quote_plus(url)
print(url_str)
url_decode = parse.unquote_plus(url_str) #url解码
print(url_decode)
1、面向过程的实现如下:
import hashlib def my_md5(s): md = hashlib.md5() md.update(s.encode()) return md.hexdigest() def get_vendorid(req_data): data_dict = {} sub_lst =req_data.split('&') #【vendorId=1697, posCode=pos006】 for i in sub_lst: #verid=1697 k,v = i.split('=') #[vendorId, 1697] data_dict.setdefault(k, v) # data_dict[k] = v print(data_dict) return data_dict.get('vendorId') def sign(req_data): verid = get_vendorid(req_data) #调用获取vendorid函数 first = my_md5(verid) astr = my_md5(first) #两次md5结果 url_str = parse.quote_plus(req_data) #url编码 res = my_md5(astr+url_str) return res data = 'vendorId=1697&posCode=pos006&ip=127.0.0.1&posVersion=2.1.1.1.1&mac=;D4-81-D7-CA-20-29;7C-67-A2-9A-06-05;7C-67-A2-9A-06-06;7C-67-A2-9A-06-09;00-00-00-00-00-0000E0' # # get_vendorid(data) # res = sign(data) # print(res)
2、面向对象的实现
class Sign(object): def __init__(self, req_data): self.req_data = req_data #这里写了self的话,在其他函数里也可以用self.xx self.get_verid() #这里调用也是可以的 self.get_sign() def md5(self,s): md = hashlib.md5() md.update(s.encode()) return md.hexdigest() def get_verid(self): data_dict = {} sub_lst = self.req_data.split('&') # 【vendorId=1697, posCode=pos006】 for i in sub_lst: # verid=1697 k, v = i.split('=') # [vendorId, 1697] data_dict.setdefault(k, v) # data_dict[k] = v print(data_dict) self.verid = data_dict.get('vendorId') def get_sign(self): self.get_verid() #verid,不调用时是不会报错的,可以在使用前先调用一下 first = self.md5(self.verid) astr = self.md5(first) # 两次md5结果 url_str = parse.quote_plus(self.req_data) # url编码 self.sign = self.md5(astr + url_str) return self.sign abc = Sign(data) # print(abc.get_sign()) print(abc.sign) #AttributeError: 'Sign' object has no attribute 'sign' # if __name__ == '__main__': # data1 = 'vendorId=1697&posCode=pos006&ip=127.0.0.1&posVersion=2.1.1.1.1&mac=;D4-81-D7-CA-20-29;7C-67-A2-9A-06-05;7C-67-A2-9A-06-06;7C-67-A2-9A-06-09;00-00-00-00-00-0000E0' # abc = Sign(data1) # # print(abc.get_sign()) # print(abc.sign) # AttributeError: 'Sign' object has no attribute 'sign' # self的内存地址: 42845464 # demo的内存地是 42845464 # self的内存地址: 42973056 # xxx的内存地是 42973056
三、self的含义
#selft代表的就是实例化之后的对象
#类变量
#实例变量(成员变量),
#类方法, @classmethod
#实例方法
#静态方法
#属性方法,不能有参数,@property
1、示例,self的使用, 类实例变量,
class Baby(): #类变量 country = 'china' #为变量,公共的变量,节省内存,只存一份,但是调用方式民实例变量是一样的 # def __init__(self,name): # print('self的内存地址:', id(self)) # self.name = name #实例变量,每个实例对象都会保存一份 # #selft代表的就是实例化之后的对象 # self.money = 5000 # self.sex = '女' def my(self): self.name = '小黑' def cry(self): print('小霸王') #装饰器 #属性方法,不能有参数, @property def hhh(self): return 198 #类方法 #1、不用实例就可以直接调用 #2、它可以通过cls使用类变量 #3、它不能调用这个类里面的其他实例方法和实例变量 @classmethod def xm(cls): #cls代表的就是Baby类 print(cls.country) print('我是类方法') # print(cls.name) #AttributeError: type object 'Baby' has no attribute ' # cls.cry() #TypeError: cry() missing 1 required positional argument: 'self' #静态方法 #用不了类方法,也用不了属性方法,也用不了实例方法,就是一个普通的函数而已 @staticmethod def xh(): print('这是静态方法,它和一个没写在类里面的函数一样') # dcg = Baby('demo') # print('demo的内存地是', id(dcg)) # zll = Baby('ljj') # print('ljj的内存地是', id(zll)) #selft对象代表的是本类对象 #因为函数 #属性方法 # b = Baby('demo') # # print(b.hhh()) #TypeError: 'int' object is not callable # print(b.hhh) #类 #需要实例后才能用 # Baby.cry() #TypeError: cry() missing 1 required positional argument: 'self' # #类变量 # Baby.country = 'USA' #类变量可以通过类名.xxx来修改的 # baby = Baby() # baby2 = Baby() # print(baby2.country) # print(baby.country) # baby.country= 'Japan' # print(baby2.country) # print(baby.country) #类方法 #1、不实列化,直接用类名调用这个xm的方法 #2、实例化之后,在通过实例化之后的对象调用xm方法,看看可以不 #3、不想实例化的时候,就可以定义成类方法 #静态方法 #静态方法: 就是一个普通函数,只不过是写在类里面而已,它用不了类变量,类方法,实例变量,实例方法 #私有 #不实例化 Baby.xm() #我是类方法 #2、 test1= Baby() test1.xm() #属性方法: #看起来是一个变量,但实际上一个方法 # b = Baby('demo') # # print(b.hhh()) #TypeError: 'int' object is not callable # print(b.hhh)
四、私有
#私有,出了类之后,就不能用了 #私有方法 #私有变量
定义私有,包括私有方法,私有变量如下:
self.__name = 'name'
def __private_method(self):
pass
1、私有示例
import redis class My(object): def __init__(self): self.__host = '127.0.0.1' self.__port = 6379 self.__passwd = '111111' self.r = redis.Redis(host=self.__host, port=self.__port, password=self.__passwd) #私有方法 def __clos(self): print('close.') def get(self, k): res = self.r.get(k) if res: return res.decode() return None def str_set(self, k, v): self.r.set(k, v) #hash类型get def hash_get(self): pass # hash类型get def hash_set(self): pass def hash_getall(self): pass #str删除key def str_del(self): pass #删除某个hash里面小key def hash_del(self): pass #清空redis里的所有key def clean(self): pass #私有,出了类之后,就不能用了 #私有方法 #私有变量 my = My() # my.port = 9999 #私有变量 # print(my.__host) #AttributeError: 'My' object has no attribute '__host' #私有方法 # my.__close() #AttributeError: 'My' object has no attribute '__close'
五、继承
1、概念
子类继承父类,即使子类不重新写什么,都将有父类的定义的变量,方法。
2、示例
class Lz(object): def __init__(self): self.money = 1000000 self.house = '3环里20套' def sing(self): print('唱歌') def dance(self): print('跳舞') def lm(self): print('找朋友') class Zxl(Lz): def dance(self): #重写了父类的方法,子类会用自己的方法 print('霹雳舞') # p1 = Zxl() # p1.sing() # p1.dance() # p1.lm() class Base(object): def __init__(self, host, port, passwd): self.host = host self.port= port self.passwd = passwd class MySql(Base): pass class Redis(Base): pass
六、使用类,面向对象封装数据访问类
1、示例代码
import pymysql class MyDB(object): # 析构函数 # 实例被销毁的时候执行 #程序结束时执行,如在本py文件时,最后执行 def __del__(self): self.cur.close() self.conn.close() print('over...') #构造函数 def __init__(self,host, user, passwd,db, port=3306, charset='utf8'): try: self.conn = pymysql.connect( host=host,user=user,passwd=passwd, port=port,charset=charset,db=db, autocommit=True,#自动提交 ) except Exception as e: print('数据库连接失败: %s' %e) else: self.cur = self.conn.cursor(cursor=pymysql.cursors.DictCursor) #返回字典 def ex_sql(self, sql): try: self.cur.execute(sql) except Exception as e: print('sql语句有问题,%s' %sql) else: #执行成功后才有结果 self.res = self.cur.fetchall() return self.res my = MyDB('127.0.0.1','demo','123456','demo') res = my.ex_sql('select * from stu;') print(res) # my.ex_sql() print('我是最后一行代码...') #结果: # 我是最后一行代码... # over...