设为首页 收藏本站
查看: 927|回复: 0

[经验分享] Python Day7

[复制链接]

尚未签到

发表于 2018-8-7 06:32:44 | 显示全部楼层 |阅读模式
继承与派生

什么是继承
  是一种新建类的方式,新建的类称为子类,子类会遗传父亲的属性,可以减少代码冗余
  在python当中,子类(派生类)可以继承一个或多个父类(基类,超类)
  在python3中定义类时不写父类默认会继承object
  在python2中需要写object
  所以,为了兼容,在定义类时可以写上默认的object
  

class Parent1(object): #python3是不需要写上(object)的,但其实是有的  pass
  

  
class Parent2:
  pass
  

  
class Sub1(Parent1):
  pass
  

  
class Sub2(Parent1,Parent2): #继承多个父类
  pass
  

print(Sub1.__bases__) #查看有哪些父类  
print(Sub2.__bases__)
  

经典类与新式类
  在Python2中类分为两种:
  1、经典类:指的就是没有继承object类的类,以及该类的子类
  2、新式类:指的就是继承object类的类,以及该类的子类
  在Python3中统一都为新式类
  继承可以实现代码重用

派生
  当然子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。
  注意:
  在子类中,新建的重名的函数属性,在编辑函数内功能的时候,有可能需要重用父类中重名的那个函数功能,应该是用调用普通函数的方式,即:类名.func(),此时就与调用普通函数无异了,因此即便是self参数也要为其传值

继承、派生示例
  

class OldboyPeople:  school = 'Oldboy'
  

  def __init__(self, name, age, sex):
  self.name = name
  self.age = age
  self.sex = sex
  

  def tell_info(self):
  print('<名字: %s 姓名: %s 性别: %s>' %(self.name,self.age,self.sex))
  

  
class OldboyStudent(OldboyPeople):
  def learn(self):
  print('%s is learning' % self.name)
  

  def tell_info(self):  #派生
  print('我是学生:',end='')
  print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex))
  

  
class OldboyTeacher(OldboyPeople):
  def teach(self):
  print('%s is teaching' %self.name)
  

  def tell_info(self):  #派生
  print('我是老师:',end='')
  print('<名字:%s 年龄:%s 性别:%s>' % (self.name, self.age, self.sex))
  

  
stu1=OldboyStudent('dzm',18,'male')
  
teacher1=OldboyTeacher('egon',18,'male')
  

  teacher1.tell_info() #子类中有tell_info则使用子类中的tell_info

属性查找
  先在对象自己的名称空间查找,再在所属的子类名称空间查找,再在子类的父类的名称空间中查找
  

class Foo:  def f1(self):
  print('Foo.f1')
  

  def f2(self): #self=obj
  print('Foo.f2')
  self.f1() #obj.f1()
  

  
class Bar(Foo):
  def f1(self):
  print('Bar.f1')
  

  
obj=Bar()
  
print(obj.__dict__)
  
obj.f2()
  

  结果:
  

{}  
Foo.f2
  
Bar.f1
  

子类重用父类的功能之直接指定
  此时就与调用普通函数无异了,因此即便是self参数也要为其传值
  示例2:
  

class OldboyPeople:  school = 'Oldboy'
  

  def __init__(self, name, age, sex):
  self.name = name
  self.age = age
  self.sex = sex
  

  def tell_info(self):
  print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex))
  

  
class OldboyStudent(OldboyPeople):
  def learn(self):
  print('%s is learning' %self.name)
  

  def tell_info(self):
  print('我是学生:',end='')
  #self.tell_info() #stu1.tell_info()
  OldboyPeople.tell_info(self) #直接调用指定类的函数,不依赖继承关系
  

  
stu1=OldboyStudent('牛榴弹',18,'male')
  

stu1.tell_info()  

  
结果:
  
我是学生:<名字:牛榴弹 年龄:18 性别:male>
  

  示例2:
  

class OldboyPeople:  school = 'Oldboy'
  

  def __init__(self, name, age, sex):
  self.name = name
  self.age = age
  self.sex = sex
  

  def tell_info(self):
  print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex))
  

  
class OldboyStudent(OldboyPeople):
  def __init__(self,name,age,sex,course,stu_id):
  # self.name=name
  #self.age=age
  #self.sex=sex
  OldboyPeople.__init__(self,name,age,sex) #调用指定类的函数,不依赖继承关系
  self.course=course
  self.stu_id=stu_id
  

  def learn(self):
  print('%s is learning' %self.name)
  

  def tell_info(self):
  print('我是学生:',end='')
  #self.tell_info() #stu1.tell_info()
  OldboyPeople.tell_info(self)
  

  
stu1=OldboyStudent('牛榴弹',18,'male','Python',1)
  

  stu1.tell_info()

组合
  代码重用的重要方式除了继承之外还有另外一种方式,即:组合
  组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

组合示例1
  

class OldboyPeople:  school = 'Oldboy'
  

  def __init__(self, name, age, sex):
  self.name = name
  self.age = age
  self.sex = sex
  

  def tell_info(self):
  print('<名字:%s 年龄:%s 性别:%s>' % (self.name, self.age, self.sex))
  

  
class OldboyStudent(OldboyPeople):
  def __init__(self, name, age, sex, course, stu_id,):
  OldboyPeople.__init__(self, name, age, sex)
  self.course = course
  self.stu_id = stu_id
  

  def learn(self):
  print('%s is learning' % self.name)
  

  def tell_info(self):
  print('我是学生:', end='')
  #self.tell_info() #stu1.tell_info()
  OldboyPeople.tell_info(self)
  

  
class OldboyTeacher(OldboyPeople):
  def __init__(self, name, age, sex, level, salary):
  OldboyPeople.__init__(self, name, age, sex)
  self.level = level
  self.salary = salary
  

  def teach(self):
  print('%s is teaching' % self.name)
  

  def tell_info(self):
  print('我是老师:', end='')
  OldboyPeople.tell_info(self)
  

  
class Date: #专门定义一个日期类
  def __init__(self,year,mon,day):
  self.year = year
  self.mon = mon
  self.day = day
  

  def tell_birth(self):
  print('出生日期是:<%s-%s-%s>' % (self.year, self.mon, self.day))
  

  学生有生日的属性,老师也有生日的属性,但学生和老师都不是生日,因此不符合什么是什么的继承关系
  但学生和老师都有生日这个属性,可以理解为什么有什么的关系
  这里使用组合,专门定义一个日期类,组合也可以减少代码重用
  

stu1 = OldboyStudent('牛榴弹', 18, 'male', 'Python', 1,) #实例化一个学生对象  
date_obj1=Date(1983, 3, 11)  #实例化一个日期对象
  
stu1.birth=date_obj1 #给stu1这个对象添加一个名为birth的属性,把上面的日期实例赋值给它
  

  看一个赋值后的stu1.birth是什么
  

print(stu1.birth)  
结果:
  
<__main__.Date object at 0x000001CEB43A2240>
  

  名为birth的属性实际指向了date_obj1这个对象,也就是指向了它后面的Date这个类
  这样就等于把两个类间接的组合到了一起
  既然已经把date_obj1这个对象赋值给了stu1.birth,那我们可以借此调用Date类里面的函数
  stu1.birth.tell_birth() #等于date_obj1.tell_birth()
  结果:
  出生日期是:<1983-3-11>

组合示例2
  

class OldboyPeople:  school = 'Oldboy'
  

  def __init__(self, name, age, sex,date_obj):
  self.name = name
  self.age = age
  self.sex = sex
  self.birth = date_obj
  

  def tell_info(self):
  print('<名字:%s 年龄:%s 性别:%s>' % (self.name, self.age, self.sex))
  

  
class OldboyStudent(OldboyPeople):
  def __init__(self, name, age, sex, stu_id,date_obj):
  OldboyPeople.__init__(self, name, age, sex,date_obj)
  self.courses=[]  #学生有课程,初始为空,让学生自己选课
  self.stu_id = stu_id
  

  def learn(self):
  print('%s is learning' % self.name)
  

  def tell_info(self):
  print('我是学生:', end='')
  # self.tell_info() #stu1.tell_info()
  OldboyPeople.tell_info(self)
  

  
class OldboyTeacher(OldboyPeople):
  def __init__(self, name, age, sex, level, salary,date_obj):
  OldboyPeople.__init__(self, name, age, sex,date_obj)
  self.level = level
  self.salary = salary
  self.courses=[]  #老师也有课程,初始为空,让老师自己选
  

  def teach(self):
  print('%s is teaching' % self.name)
  

  def tell_info(self):
  print('我是老师:', end='')
  OldboyPeople.tell_info(self)
  

  
class OldboySale(OldboyPeople):
  def __init__(self,name,age,sex,kpi,date_obj):
  OldboyPeople.__init__(self,name,age,sex,date_obj)
  self.kpi=kpi
  

  def tell_info(self):
  print('我是销售: ',end='')
  OldboyPeople.tell_info(self)
  

  
class Date:
  def __init__(self,year,mon,day):
  self.year = year
  self.mon = mon
  self.day = day
  

  def tell_birth(self):
  print('出生日期是:<%s-%s-%s>' % (self.year, self.mon, self.day))
  

  
class Course:     #新定义一个课程类
  def __init__(self,name,price,period):
  self.name=name
  self.price=price
  self.period=period
  

  def tell_info(self):
  print('课程详细信息:<%s,%s,%s>' %(self.name,self.price,self.period))
  

#实例化两个课程  
Python=Course('python自动化养猪',3000,'3mon')
  
Linux=Course('大数据分析-linux',3000,'3mon')
  #实例化一个日期对象
  
date_obj=Date(1993,3,13)
  

  
#初始化时直接设定生日属性,这里与示例1不同,但原理上一样使用组合
  
# teacher1=OldboyTeacher('egon',18,'male',100,3000,date_obj)
  

  
# teacher1.courses.append(Python)
  
# teacher1.courses.append(Linux)
  
#
  
# # print(teacher1.courses)
  
# for course in teacher1.courses:
  
#     course.tell_info()
  

stu1=OldboyStudent('xxxx',28,'female',1,date_obj)  
# print(stu1.courses)
  

  
stu1.courses.append(Python)
  
stu1.courses.append(Linux)
  

  
print(stu1.courses)
  
结果:
  
[<__main__.Course object at 0x0000024AD3683518>, <__main__.Course object at 0x0000024AD3683550>]
  

for course in stu1.courses:  #使用for循环可以直接取出课程  course.tell_info()
  
结果:
  
课程详细信息:<python自动化养猪,3000,3mon>
  
课程详细信息:<大数据分析-linux,3000,3mon>
  

抽象类
  从实现角度来看,抽象类与普通类的不同之处在于:抽象类中只能有抽象方法(没有实现功能),该类不能被实例化,只能被继承,且子类必须实现抽象方法。
  抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计
  这里模拟linux上一切皆文件的概念
  import abc
  定义一个父类,定义读写两个函数
  

class File(metaclass=abc.ABCMeta): #指定一个类的原类,metaclass是类似创建类的模板  @abc.abstractmethod  #调用一个装饰器,意味着继承这个父类的子类必须有这个函数名称
  def read(self):
  pass
  

  @abc.abstractmethod
  def write(self):
  pass
  

  
class Disk(File): #磁盘子类
  def read(self):
  print('disk read')
  

  def write(self):
  print('disk write')
  

  
class Process(File): #进程子类
  def read(self):
  print('Process read')
  

  def write(self):
  print('Process write')
  

  实例出两个对象
  

d=Disk()  
p=Process()
  

  在使用时无需关心到底是什么,使用方法都是一样的
  这样大家都是被归一化了,也就是一切皆文件的思想
  

d.read()  
d.write()
  

  
p.read()
  
p.write()
  

继承实现的原理

深度优先与广度优先
DSC0000.jpg

DSC0001.jpg


python如何实现的继承
  对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表。
  Python3提供了一个.mro方法,可以以列表形式显示出查找顺序
  

...........省略...........  
f1=F()
  
print(F.mro())
  
[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
  

  为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止

子类重用父类的功能之super
  理解了继承原理,就可以看一下另一种子类重用父类功能的方法super()
  当你使用super()函数时,Python会在MRO列表上继续搜索下一个类
  两种子类重用父类功能的方法最好不要混用
  super示例1
  

class OldboyPeople:  school = 'Oldboy'
  

  def __init__(self, name, age, sex):
  self.name = name
  self.age = age
  self.sex = sex
  

  def tell_info(self):
  print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex))
  

  
class OldboyStudent(OldboyPeople):
  def __init__(self,name,age,sex,course):
  # OldboyPeople.__init__(self,name,age,sex) #这种方法指名道姓,与继承关系无关
  super(OldboyStudent,self).__init__(name,age,sex)
  self.course=course
  

  def tell_info(self):
  print('我是学生: ',end='')
  # OldboyPeople.tell_info(self)
  super(OldboyStudent,self).tell_info()
  

  
stu1=OldboyStudent('egon',18,'male','python')
  

  
# print(stu1.name,stu1.age,stu1.sex,stu1.course)
  
stu1.tell_info()
  

  示例2
  

class Foo:  def f2(self):
  print('====?>')
  

  def f1(self):
  print('Foo.f1')
  super().f2()
  

  
class Bar:
  def f2(self):
  print('Bar f2')
  

  
class Sub(Foo,Bar):
  pass
  

s=Sub()  
# print(Sub.mro())
  
# [<class '__main__.Sub'>,
  
# <class '__main__.Foo'>,
  
# <class '__main__.Bar'>,
  
#  <class 'object'>]
  

  
s.f1()
  

  结果:
  

Foo.f1  
Bar f2  #结果反映出调用是从MRO列表当前的位置往后找,而不是找它自己的
  

  注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表

多态与多态性

多态
  多态指的是一类事物有多种形态,比如
  动物有多种形态:人,狗,猪
  

import abc  
class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
  @abc.abstractmethod
  def talk(self):
  pass
  

  
class People(Animal): #动物的形态之一:人
  def talk(self):
  print('say hello')
  

  
class Dog(Animal): #动物的形态之二:狗
  def talk(self):
  print('say wangwang')
  

  
class Pig(Animal): #动物的形态之三:猪
  def talk(self):
  print('say aoao')
  

多态性

什么是多态动态绑定(在继承的背景下使用时,有时也称为多态性)
  多态性是指在不考虑实例类型的情况下使用实例,多态性分为静态多态性和动态多态性
  静态多态性:如任何类型都可以用运算符+进行运算
  动态多态性:如下
  

peo=People()  
dog=Dog()
  
pig=Pig()
  

  peo、dog、pig都是动物,只要是动物肯定有talk方法
  于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
  

peo.talk()  
dog.talk()
  
pig.talk()
  

  更进一步,我们可以定义一个统一的接口来使用
  

def func(obj):  obj.talk()
  

  
func(peo)
  
func(pig)
  

  结果:
  

say hello  
say aoao
  

为什么要用多态性(多态性的好处)
  1.增加了程序的灵活性
  以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)
  2.增加了程序额可扩展性
  通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用

鸭子类型
  Python崇尚鸭子类型
  “鸭子类型”的语言是这么推断的:一只鸟走起来像鸭子、游起泳来像鸭子、叫起来也像鸭子,那它就可以被当做鸭子。
  也就是说,它不关注对象的类型,而是关注对象具有的行为(方法)。
  举例:
  序列类型有多种形态:字符串,列表,元组,但他们直接没有直接的继承关系
  str,list,tuple都是序列类型
  

s=str('hello')  
l=list([1,2,3])
  
t=tuple((4,5,6))
  

  我们可以在不考虑三者类型的前提下使用s,l,t
  

s.__len__()  
l.__len__()
  
t.__len__()
  

  
len(s)
  
len(l)
  
len(t)
  

封装

如何隐藏
  1、开头的属性只是一种语法意义上的变形,并不会真的限制外部的访问
  2、这种变形只在类定义阶段发送一次,类定义之后再新增的开头的属性不会变形
  3、这种隐藏只对外不对内,因为类内部定义的属性在类定义阶段统一发生变形
  

class Foo:  __N=1 #_Foo__N=1
  def __init__(self,x,y):
  self.x=x
  self.__y=y #self._Foo__y=y
  

  def __f1(self): #_Foo__f1
  print('f1')
  

  def f2(self):
  print(self.__N,self.__y) #print(self._Foo__N,self._Foo__y)
  

  在知道规则的情况下可以找到所需内容,可见并不是真正意义的隐藏
  

print(Foo._Foo__N)  
print(Foo._Foo__f1)
  

  结果:
  

1  
<function Foo.__f1 at 0x000001FAB8468AE8>
  

obj=Foo(1,2)  
print(obj.__dict__)
  
print(obj._Foo__y)
  

  结果:
  

{'x': 1, '_Foo__y': 2}  
2
  

obj=Foo(1,2)  
obj.f2()
  
结果:
  
1 2
  

封装的真正意义
  封装数据属性的目的:外部无法直接访问数据属性,类内部开放接口,然后可以在接口内严格控制对属性的增删改查操作
  

class People:  def __init__(self,name,age):
  self.set_info(name,age)
  

  def tell_info(self):
  print("姓名 %s 年龄 %s" %(self.__name,self.__age))
  

  def set_info(self,name,age):
  if type(name) is not str:
  raise TypeError('name must be str')
  if type(age) is not int:
  raise TypeError('age must be int')
  

  self.__name = name
  self.__age = age
  

  
p=People('dzm',18)
  
p.tell_info()
  

  修改
  

p.set_info('DZM',20)  
p.tell_info()
  

  封装方法的目的是:隔离复杂度
  

class ATM:  def __card(self):
  print('插卡')
  def __auth(self):
  print('用户认证')
  def __input(self):
  print('输入取款金额')
  def __print_bill(self):
  print('打印账单')
  def __take_money(self):
  print('取款')
  

  def withdraw(self):
  self.__card()
  self.__auth()
  self.__input()
  self.__print_bill()
  self.__take_money()
  

  
d=ATM()
  
d.withdraw()
  

  取款是功能,而这个功能有很多功能组成:插卡、密码认证、输入金额、打印账单、取钱
  对使用者来说,只需要知道取款这个功能即可,其余功能我们都可以隐藏起来,很明显这么做
  隔离了复杂度,同时也提升了安全性

封装之property
  property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
  为什么要用property
  将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的
  这种特性的使用方式遵循了统一访问的原则
  

class People:  def __init__(self,name,age,height,weight):
  self.name=name
  self.age=age
  self.height=height
  self.weight=weight
  

  @property
  def bmi(self):
  return self.weight / (self.height ** 2)
  

egon=People('egon',18,1.80,75)  
egon.height=1.82
  
print(egon.bmi())
  

  此时获取bmi要调取类中的函数,但bmi也应该是人的属性之一,像查看属性(egon.bmi)那样查看岂不更好?使用@property实现了这一点
  print(egon.bmi)
  

class People:  def __init__(self,name,):
  self.__name=name
  

  @property  #针对的是查看一个属性的行为会触发下面这个函数的执行
  def name(self):
  return self.__name
  

  @name.setter  #设置
  def name(self,obj):
  if type(obj) is not str:
  raise TypeError('name must be str')
  self.__name=obj
  

  @name.deleter #删除
  def name(self):
  # del self.__name
  raise PermissionError('不让删')
  

  @name.setter和@name.deleter都是固定用法
  

egon=People('egon')  
print(egon.name)
  

  修改
  

egon.name='EGON' #使用了@name.setter就可以像修改属性那样操作了  
egon.name=35357 #因为做了判断,所以此时会返回异常'name must be str'
  
print(egon.name)
  

  del egon.name #使用了@name.deleter就可以像删除属性那样操作了
  真正的封装是,经过深入的思考,做出良好的抽象,给出“完整且最小”的接口,并使得内部细节可以对外透明
  (注意:对外透明的意思是,外部调用者可以顺利的得到自己想要的任何功能,完全意识不到内部细节的存在)

绑定方法与非绑定方法
  这里以从文件传参来举例
  

import settings #从文件读取HOST和PORT  
import hashlib
  
import time
  

  
class MySQL:
  def __init__(self,host,port):
  self.host=host
  self.port=port
  

  def func(self):
  print('%s 说:你好啊我的天' %self.name)
  

  #从文件传参数
  @classmethod  #当需要传进来的是类时,使用@classmethod
  def from_conf(cls): #此时cls等于MySQL
  return cls(settings.HOST,settings.PORT)
  

  @staticmethod #非绑定方法
  def create_id(n):
  m=hashlib.md5()
  m.update(str(time.clock()+n).encode('utf-8'))
  return m.hexdigest()
  

  提醒:
  绑定方法:绑定给谁就应该由谁来调用,谁来调用就会把谁当做第一个参数自动传入
  conn=MySQL.from_conf()
  当函数体代码不需要类传进来也不需要对象自动传进来时,这种函数就定义成非绑定方法
  此时我们来看看结果
  

print(MySQL.create_id)  
print(conn.create_id)
  

  结果:
  

<function MySQL.create_id at 0x0000013A42048E18>  
<function MySQL.create_id at 0x0000013A42048E18>
  

  使用@staticmethod后无论是对象调用还是类调用都显示为一个函数而已
  使用非绑定方法不意味着不需要传参
  

print(MySQL.create_id(1))  
print(conn.create_id(2))
  

  结果:
  

85a3525bf7884cad61c0c2fea69f08ed  
38dea5a04f7a37b41f69eb5c7b396787
  

内置函数补充

isinstance 判断类型
  判断类型可以不用type了
  

l=list([])  

  
print(type(l) is list)
  
print(isinstance(l,list))
  

  判断l是不是list的实例
  结果:
  True

issubclass
  判断一个类是不是另一个类的子类
  

class Foo:  pass
  

  
class Bar(Foo):
  pass
  

  print(issubclass(Bar,Foo))
  检查Bar类是否是 Foo类的派生类(子类)
  结果:
  True

面向对象进阶

反射
  能够通过字符串映射到属性身上
  

class Foo:  def __init__(self,name):
  self.name=name
  

  def f1(self):
  print('===>f1')
  

  
obj=Foo('egon')
  

正常调用属性  
# obj.name #obj.__dict__['name']
  

  hasattr 判断object中有没有一个name字符串对应的方法或属性
  

print(hasattr(obj,'name')) #等同于obj.name  
print(hasattr(obj,'f1')) #等同于obj.f1
  

  有就返回True
  getattr
  

if hasattr(obj,'f1'): 判断obj下与没有f1这个属性或发放  f=getattr(obj,'f1') #f=obj.f1 有则拿到它,通过字符串的方式
  f() #拿到一个内存地址,加括号直接执行
  
print(getattr(obj,'xxx',None)) #None是默认返回值,如果你不做判断直接获取的话,若没有则会报错,此时加个None,会返回None
  

  setattr #设置(添加、修改)
  

setattr(obj,'x',1) #等同于obj.x=1  
print(obj.__dict__) #检查一下是否有了
  

  delattr  #删除
  

del obj.name  
delattr(obj,'name')
  
print(obj.__dict__)
  

  使用示例1:
  

class FtpClient:  def __init__(self,host,port):
  self.host=host
  self.port=port
  self.conn='xxx'
  

  def interactie(self):
  while True:
  cmd=input('>>: ').strip()
  if not cmd:continue
  cmd_l=cmd.split()
  print(cmd_l)
  if hasattr(self,cmd_l[0]):
  func=getattr(self,cmd_l[0])
  func(cmd_l)
  

  def get(self,cmd_l):
  print('geting...',cmd_l)
  

  def put(self,cmd_l):
  print('putting....',cmd_l)
  

  
client=FtpClient('1.1.1.1',23)
  

  
client.interactie()
  

类的内置方法

str
  内置方法是在某种行为发生的时候默认触发
  

class People:  def __init__(self,name,age):
  self.name=name
  self.age=age
  

  def __str__(self):
  return '<name:%s age:%s>' %(self.name,self.age)
  # 在打印对象的时候不要打印内存地址,希望打印有用的东西
  

egon=People('egon',18)  
print(egon) #print(egon.__str__())
  

  结果:
  

<name:egon age:18>  

  这个str函数默认就有
  在打印时触发
  默认打印的就是内存地址

del
  注:如果产生的对象仅仅只是python程序级别的(用户级),那么无需定义del
  如果产生的对象的同时还会向操作系统发起系统调用,即一个对象有用户级与内核级两种资源,比如(打开一个文件,创建一个数据库链接),则必须在清除对象的同时回收系统资源,这就用到了del
  

f=open('a.txt','w',encoding='utf-8')  
f.read()
  
f.close()
  

  
class Foo:
  def __del__(self):
  print('del---->')
  

obj=Foo()  
del obj
  
print('主')
  

  结果:
  

del---->  

  

class Mysql:  def __init__(self,host,port):
  self.host=host
  self.port=port
  self.conn=Connect(host,port)
  

  def __del__(self): #回收
  self.conn.close() #会先回收这个链接(操作系统资源)
  

  
m=Mysql('1.1.1.1',3306)
  
m.conn.execute('select * from db.user;')
  

  先回收操作系统资源再回收m这个对象

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-547813-1-1.html 上篇帖子: python json文件的使用 下篇帖子: 如何将Mac OS X10.9下的Python2.7升级到最新的Python3.3
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表