首页 > 代码库 > 面向对象-day07
面向对象-day07
一、类与对象
1、面向对象的程序设计及存在的意义
面向过程:
面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。
优点:复杂的东西简单化,极大的降低了程序的复杂度
缺点:功能单一性,一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身。
应用场景:变动极少的一旦完成基本很少改变的场景,著名的例子有Linux内核、git、Apache HTTP Server等。
面向对象:
面向对象的程序设计的核心是对象(上帝式思维),要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。一切皆对象。
优点:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改会反映到整个游戏中的这个人物。
缺点:可控性差,无法像面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法预测最终结果。于是我们经常看到一个游戏人某一参数的修改极有可能导致阴霸的技能出现,一刀砍死3个人,这个游戏就失去平衡。
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方。
面向对象的程序设计并不是全部,对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。
2、类和对象
1)python中一切皆为对象,且python3统一了类与类型的概念,类型就是类。如字典类型就是类。
>>> dict #类型dict就是类dict <class ‘dict‘> >>> d=dict(name=‘egon‘) #实例化 >>> d.pop(‘name‘) #向d发一条消息,执行d的方法pop ‘egon‘
2)在python中,类是一系列对象共有的特征(变量的定义)与技能(函数的定义)的结合体,而对象是变量与方法(指向类的函数)的结合体。
1 """ 2 声明类:类在定义时如果有print参数,会直接执行打印。 3 class 类名: 4 ‘‘‘文档注释‘‘‘ 5 类体 6 """ 7 8 #类是一系列对象共有的特征(变量的定义)与技能(函数的定义)的结合体 9 class Chinese: 10 country=‘China‘ 11 12 # Chinese.__init__(p1,‘egon‘,‘18‘,‘male‘) 13 def __init__(self,name,age,sex): 14 #p1.Name=name;p1.Age=age,p1.Sex=sex 15 self.Name=name 16 self.Age=age 17 self.Sex=sex 18 19 20 def talk(self): 21 print(‘talking‘,self) 22 23 #属性的引用 24 print(Chinese.country) #打印Chinese类中的country属性,如果属性是变量则直接打印结果 25 print(Chinese.talk) #打印Chinese类中的talk函数属性,实际打印的是函数的内存地址,需要加()括号才能执行 26 Chinese.talk(123) #加括号执行talk函数,并传值123 27 Chinese.x=1 #新增变量属性 28 print(Chinese.x) #打印新增的变量属性 29 Chinese.country=123123123123123 #修改变量属性的值 30 print(Chinese.country) #打印被修改属性的值 31 32 """ 33 输出: 34 China 35 <function Chinese.talk at 0x0000000002811048> 36 talking 123 37 1 38 123123123123123 39 """ 40 41 """ 42 类名称空间与对象/实例名称空间,创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 43 """ 44 45 #类名称空间 46 print(Chinese.__dict__) 47 48 #对象的空间 49 p1=Chinese(‘egon‘,‘18‘,‘male‘) #Chinese.__init__(p1,‘egon‘,‘18‘,‘male‘) 50 p2=Chinese(‘alex‘,‘180‘,‘male‘)
3)类的两种用法:
1 """ 2 类的两种用法 3 4 """ 5 class Chinese: 6 country = ‘China‘ 7 def __init__(self,name,age): 8 # print(‘====>‘) 9 self.name=name #p1.name=‘egon‘ 10 self.age=age #p1.age=18 11 12 def talk(self): 13 print(‘say chinese‘,self) 14 15 16 #类的第一种用法:实例化(__init__与self) 17 p1=Chinese(‘egon‘,18) #__init__(p1,‘egon‘,18),__init__默认参数self会把自己当成值传入,从参数二开始为自定义的参数。 18 19 #类的第二种用法:属性引用(类名.属性)(增删改查) 20 print(Chinese.country) #类的数据属性 21 print(Chinese.__init__) #类的函数属性 22 """ 23 输出: 24 China 25 <function Chinese.__init__ at 0x000000000252AF28> 26 """ 27 28 print(Chinese.__dict__) #查看类的属性字典,或者说名称空间 29 """ 30 输出: 31 {‘__module__‘: ‘__main__‘, ‘country‘: ‘China‘, ‘__init__‘: <function Chinese.__init__ at 0x000000000252AF28>, ‘talk‘: <function Chinese.talk at 0x0000000002531048>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘Chinese‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘Chinese‘ objects>, ‘__doc__‘: None} 32 """ 33 34 print(Chinese.country) #调用执行 35 print(Chinese.__dict__[‘country‘]) #也可以通过属性字典执行 36 """ 37 输出: 38 China 39 China 40 """
4)类属性的补充:
一:我们定义的类的属性到底存到哪里了?有两种方式查看 dir(类名):查出的是一个名字列表 类名.__dict__:查出的是一个字典,key为属性名,value为属性值 二:特殊的类属性 类名.__name__# 类的名字(字符串) 类名.__doc__# 类的文档字符串 类名.__base__# 类的第一个父类(在讲继承时会讲) 类名.__bases__# 类所有父类构成的元组(在讲继承时会讲) 类名.__dict__# 类的字典属性 类名.__module__# 类定义所在的模块 类名.__class__# 实例对应的类(仅新式类中)
5)对象是关于类而实际存在的一个例子,即实例。
1 #对象/实例 2 p1=Chinese(‘egon‘,18) #__init__(p1,‘egon‘,18) 3 print(p1.name) 4 print(p1.age) 5 6 print(p1.__dict__) 7 print(p1.__dict__[‘name‘]) 8 9 """ 10 egon 11 18 12 {‘name‘: ‘egon‘, ‘age‘: 18} 13 egon 14 """
对象/实例只有一种用法:属性引用。对象/实例本身只有数据属性,但是python的class机制会将类的函数绑定到对象上,称为对象的方法,或者叫绑定方法,绑定方法唯一绑定一个对象,同一个类的方法绑定到不同的对象上,属于不同的方法,内存地址都不会一样。
>>> g1.attack #对象的绑定方法 <bound method Garen.attack of <__main__.Garen object at 0x101348dd8>> >>> Garen.attack #对象的绑定方法attack本质就是调用类的函数attack的功能,二者是一种绑定关系 <function Garen.attack at 0x101356620>
6)类名称空间与对象/实例名称空间
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性
而类有两种属性:数据属性和函数属性,其中类的数据属性是共享给所有对象的,而类的函数属性是绑定到所有对象的。
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
#类名称空间 print(Chinese.__dict__) #对象的空间 p1=Chinese(‘egon‘,‘18‘,‘male‘) #Chinese.__init__(p1,‘egon‘,‘18‘,‘male‘) p2=Chinese(‘alex‘,‘180‘,‘male‘)
7)记数功能,记录对象执行了几次
1 class t1: 2 count = 0 3 def __init__(self): 4 t1.count+=1 5 6 a1 = t1() 7 a2 = t1() 8 a3 = t1() 9 print(t1.count) 10 11 """ 12 输出: 13 3 14 """
二、继承
1、什么是继承:一种创建新的类的方式
继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类
python中类的继承分为:单继承和多继承
class ParentClass1: #父类1 pass class ParentClass2: #父类2 pass class SubClass1(ParentClass1): #子类1继承父类1,单继承,基类是ParentClass1,派生类是SubClass pass class SubClass2(ParentClass1,ParentClass2): #子类2 继承父类1和父类2,python支持多继承,用逗号分隔开多个继承的类 pass #查看继承关系,__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类 print(SubClass1.__bases__) print(SubClass2.__bases__) """ 输出: (<class ‘__main__.ParentClass1‘>,) (<class ‘__main__.ParentClass1‘>, <class ‘__main__.ParentClass2‘>) """
提示:如果没有指定基类,python的类会默认继承object类,object是所有python类的基类,它提供了一些常见方法(如__str__)的实现。
>>> ParentClass1.__bases__ (<class ‘object‘>,) >>> ParentClass2.__bases__ (<class ‘object‘>,)
2、python2与python3中类的区别
1)python2中类分为:新式类与经典类
class Foo(object): #新式类 pass class Bar: #经典类 pass #默认是经典类,新式类需要在定义类时加object参数 class classname(object): pass
2)python3中类全都是新式类
class Foo: #新式类 pass print(Foo.__bases__) #(<class ‘object‘>,)
3、继承的实现原理
新式类是从左到右找,如果有最后有同一个父类,则找的时候,不找最后一个共同的父类,直到最后一个分支走完再到共同的父类。
而在经典类中,是深度的,直接找到最后一个共同父类,再往右找。
经典类:深度优先,F->D->B->A->E->C->H
新式类:广度优先,F->D->B->E->C->H->A
1 #新式类:广度优先,继承顺序 F->D->B->E->C->H->A 2 3 class A: 4 # def test(self): 5 # print(‘from A‘) 6 pass 7 class B(A): 8 # def test(self): 9 # print(‘from B‘) 10 pass 11 class C(A): 12 # def test(self): 13 # print(‘from C‘) 14 pass 15 16 class D(B): 17 # def test(self): 18 # print(‘from D‘) 19 pass 20 21 class E(C): 22 # def test(self): 23 # print(‘from E‘) 24 pass 25 26 class H(A): 27 def test(self): 28 print(‘from H‘) 29 pass 30 class F(D,E,H): 31 # def test(self): 32 # print(‘from F‘) 33 pass 34 35 f=F() 36 f.test() 37 print(F.mro())
4、寻找继承关系
继承的好处一:减少冗余代码
类调用的时候,默认先找自已的__init__方法,再找找父类的__init__ 。如果指定了方法,会先找自已的方法,如果没有,再找父类中。
1 class Sub: 2 def __init__(self): 3 self.bar=123 4 def bar(self): 5 print(‘Sub.bar‘) 6 7 s=Sub() 8 print(s.__dict__) #类的名称空间字典,包含类的数据属性 9 print(s.__dict__[‘bar‘]) #可通过字典方式打印类中数据属性的值 10 """ 11 输出: 12 {‘bar‘: 123} 13 123 14 """
1 class Parent: 2 def foo(self): 3 print(‘Parent.foo‘) # 2 找到父类的foo后打印Parent.foo 4 self.bar() #s.bar() # 3 这里的self是s,因为是s执行的所以把自己作为第一参数传入,也就是s.bar() ,执行时还会找自己 5 6 def bar(self): 7 print(‘Parent.bar‘) 8 9 10 class Sub(Parent): 11 def bar(self): # 4 找到自己里的bar属性 12 print(‘Sub.bar‘) # 5 执行打印Sub.bar 13 14 s=Sub() 15 s.foo() # 1 子类先找自己,没有foo属性,找父类的foo 16 17 """ 18 输出: 19 Parent.foo 20 Sub.bar 21 """
在子类定义新的属性,覆盖掉父类的属性,称为派生
1 class Animal: 2 def __init__(self, name, age, sex): 3 self.name = name 4 self.age = age 5 self.sex = sex 6 7 def eat(self): 8 print(‘eating‘) 9 10 def talk(self): 11 print(‘%s 正在叫‘ %self.name) 12 13 14 class People(Animal): 15 def __init__(self, name, age, sex,education): #在继承父类的属性同时,增加参数education 16 Animal.__init__(self,name,age,sex) 17 self.education=education 18 19 def talk(self): #定义自己的talk属性,覆盖掉父类的属性 20 Animal.talk(self) #调用父类的talk属性(可忽略,只为更直观看出区别) 21 print(‘%s say hello‘ %self.name) 22 23 class Pig(Animal): 24 pass 25 26 class Dog(Animal): 27 pass 28 29 30 peo1=People(‘alex‘,18,‘male‘,‘小学肄业‘) #People.__init__ 31 32 pig1=Pig(‘wupeiqi‘,20,‘female‘) 33 34 dog1=Dog(‘yuanhao‘,30,‘male‘) 35 36 print(peo1.education) #只有peo1有education 37 """ 38 输出: 39 小学肄业 40 """ 41 42 peo1.talk() 43 pig1.talk() 44 dog1.talk() 45 46 """ 47 输出: 48 alex 正在叫 49 alex say hello 50 wupeiqi 正在叫 51 yuanhao 正在叫 52 """
重用父类的方法:
Python2中使用super(Bar,self).test()
python中可以使用super(Bar,self).test() 也可以简写成super().test()
1 class Bar(Foo1,Foo2): 2 def test(self): 3 # Foo1.test(self) 4 # Foo2.test(self) 5 super().test() 6 print(‘bar‘) 7 print(Bar.mro()) 8 b=Bar() 9 b.test()
最后,继承父类 最好用super().test()
三、多态与多态性
1 #多态是同一种事物的多种形态 2 class Animal: 3 def talk(self): 4 print(‘正在叫‘) 5 6 7 class People(Animal): 8 def talk(self): 9 print(‘say hello‘) 10 11 class Pig(Animal): 12 def talk(self): 13 print(‘哼哼哼‘) 14 15 class Dog(Animal): 16 def talk(self): 17 print(‘汪汪汪‘) 18 19 20 class Cat(Animal): 21 def talk(self): 22 print(‘喵喵喵‘) 23 24 peo1=People() 25 pig1=Pig() 26 dog1=Dog() 27 cat1=Cat() 28 29 30 #多态性 31 32 # peo1.talk() 33 # dog1.talk() 34 # pig1.talk() 35 36 37 def func(x): 38 x.talk() 39 40 41 func(peo1) 42 func(pig1) 43 func(dog1) 44 func(cat1)
四、封装
封装(隐藏)
在属性前加两下划线 __x 就代表隐藏了,调用时 _类名__属性名
1 class Foo: 2 __x=1 #_Foo__x 3 def __test(self): #_Foo__test 4 print(‘from test‘) 5 print(Foo.__dict__) 6 print(Foo.__x) 7 Foo.test(123) 8 9 """ 10 输出: 11 {‘__module__‘: ‘__main__‘, ‘_Foo__x‘: 1, ‘_Foo__test‘: <function Foo.__test at 0x024D18E8>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘Foo‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘Foo‘ objects>, ‘__doc__‘: None} 12 """
__x 这种语法只在定义阶段变形
1 def tell_info(self): 2 print(‘人的名字是:%s ,人的性别是:%s,人的年龄是:%s‘ %( 3 self.__name, #p._People__name 4 self.__age, 5 self.__sex))
父类只调用父类自己的属性,子类调用父类中的隐藏属性
1 class Parent: 2 def foo(self): 3 print(‘from parent.foo‘) 4 self.__bar() #self._Parent__bar() 5 6 def __bar(self): #_Parent__bar 7 print(‘from parent.bar‘) 8 9 10 class Sub(Parent): 11 # def __bar(self): #_Sub__bar 12 # print(‘from SUb.bar‘) 13 pass 14 15 #子类调用父类中的隐藏属性 16 s=Sub() 17 s.foo() 18 s._Parent__bar() 19 20 """ 21 输出: 22 from parent.foo 23 from parent.bar 24 from parent.bar 25 """
设置及类型检查:
1 class People: 2 def __init__(self,name,age): 3 self.__name=name 4 self.__age=age 5 6 def tell_info(self): 7 print(‘人的名字是:%s ,人的年龄是:%s‘ %( 8 self.__name, #p._People__name 9 self.__age)) 10 11 def set_info(self,x,y): 12 if not isinstance(x,str): 13 raise TypeError(‘名字必须是字符串类型‘) 14 if not isinstance(y,int): 15 raise TypeError(‘年龄必须是整数类型‘) 16 17 self.__name=x 18 self.__age=y 19 20 21 p=People(‘alex‘,1000) 22 p.tell_info()
装饰器,property
1 class Foo: 2 @property 3 def test(self): 4 print(‘from fooo‘) 5 # test=property(test) 6 7 f=Foo() 8 # f.test() 9 f.test
使用@property,在执行类中属性(函数)时,不需要加括号
1 class People: 2 def __init__(self,name,permmission=False): 3 self.__name=name 4 self.permmission=permmission 5 6 def get_name(self): 7 return self.__name 8 9 def set_name(self,value): 10 if not isinstance(value,str): 11 raise TypeError(‘名字必须是字符串类型‘) 12 self.__name=value 13 14 def del_name(self): 15 if not self.permmission: 16 raise PermissionError(‘不允许的操作‘) 17 del self.__name 18 name=property(get_name,set_name,del_name) 19 p=People(‘egon‘) 20 21 # print(p.name) 22 # 23 # p.name=‘egon666‘ 24 # print(p.name) 25 # 26 # p.name=35357 27 p.permmission=True 28 del p.name
1 #算成人的BMI指数,当指数有变化时,需要重新设置值,需要用到property 2 class People(): 3 def __init__(self,name,weight,height): 4 self.name=name 5 self.weight=weight 6 self.height=height 7 @property 8 def bmi(self): 9 return self.weight / (self.height ** 2) 10 11 p=People(‘merry‘,60,1.63) 12 p.height=1.60 #重新设置身高 13 print(p.bmi) 14 """ 15 输出: 16 23.437499999999996 17 """
五、绑定方法与非绑定方法
类中定义的函数分成两大类:
一:绑定方法(绑定给谁,谁来调用就自动将它本身当作第一个参数传入):
1. 绑定到类的方法:用classmethod装饰器装饰的方法。
为类量身定制
类.boud_method(),自动将类当作第一个参数传入
(其实对象也可调用,但仍将类当作第一个参数传入)
2. 绑定到对象的方法:没有被任何装饰器装饰的方法。
为对象量身定制
对象.boud_method(),自动将对象当作第一个参数传入
(属于类的函数,类可以调用,但是必须按照函数的规则来,没有自动传值那么一说)
二:非绑定方法:用staticmethod装饰器装饰的方法
1. 不与类或对象绑定,类和对象都可以调用,但是没有自动传值那么一说。就是一个普通工具而已
注意:与绑定到对象方法区分开,在类中直接定义的函数,没有被任何装饰器装饰的,都是绑定到对象的方法,可不是普通函数,对象调用该方法会自动传值,而staticmethod装饰的方法,不管谁来调用,都没有自动传值一说
1 lass Foo: 2 def test1(self): 3 pass 4 @classmethod 5 def test2(cls): 6 print(cls) 7 @staticmethod 8 def test3(): 9 pass 10 11 f=Foo() 12 print(f.test1) 13 print(Foo.test2) 14 print(Foo.test3) 15 print(f.test3) 16 17 18 import settings 19 class MySQL: 20 def __init__(self,host,port): 21 self.host=host 22 self.port=port 23 print(‘conneting...‘) 24 @classmethod 25 def from_conf(cls): 26 return cls(settings.HOST,settings.PORT) #MySQL(‘127.0.0.1‘,3306) 27 def select(self): #绑定到对象的方法 28 print(self) 29 print(‘select function‘) 30 31 # conn=MySQL(‘192.168.1.3‘,3306) 32 # conn.select() 33 34 # conn1=MySQL(‘192.168.1.3‘,3306) 35 conn2=MySQL.from_conf()
1 # 导入hashlib模块,生成具有唯一性的md5码 2 import hashlib 3 import time 4 def create_id(): 5 m=hashlib.md5(str(time.clock()).encode(‘utf-8‘)) 6 return m.hexdigest() 7 8 print(time.clock()) 9 print(time.clock()) 10 print(time.clock()) 11 12 print(create_id()) 13 print(create_id()) 14 print(create_id()) 15 print(create_id()) 16 17 """ 18 输出: 19 8.924575290617639e-07 20 0.03692453780740142 21 0.037000396697371665 22 f5f76005f8b828655079c01ba30dae92 23 09540f3e7a687b33dd619a724a21c265 24 34d6688a54832ac08485ba835f76d758 25 6aa369d127d464059bf13908cb9ef29a 26 """
总结:
1 #绑定到类的方法(classmethod)的应用场景,使用配置文件中的默认参数 2 import settings #导入配置文件模块 3 """ 4 settings py文件内容: 5 HOST=‘127.0.0.1‘ 6 PORT=3306 7 """ 8 class MySQL: 9 def __init__(self,host,port): 10 self.host=host 11 self.port=port 12 print(‘connecting mysql...‘) 13 @classmethod 14 def from_conf(cls): 15 return cls(settings.HOST,settings.PORT) 16 17 def select(self): 18 print(self) 19 print(‘select function‘) 20 21 conn1=MySQL(‘192.168.1.1‘,3306) 22 conn1.select() 23 """ 24 输出:方法一,传参使用的是绑定到对象的方法,def __init__(self,host,port): 25 connecting mysql... 26 <__main__.MySQL object at 0x031A0750> 27 select function 28 """ 29 conn2=MySQL.from_conf() 30 conn2.select() 31 """ 32 输出:方法二,使用绑定到类的方法,调用导入配置文件模块中的默认配置 33 connecting mysql... 34 <__main__.MySQL object at 0x028B0450> 35 select function 36 """ 37 # 类中的__str__方法(类的内置方法) 38 class MySQL: 39 @staticmethod 40 def __str__(): 41 return "11111" 42 aa = MySQL() 43 print(aa) #11111,打印对象就会自动执行类中的__str__ 44 print(MySQL) #<class ‘__main__.MySQL‘>
六、staticmethod与classmethod的区别
""" settings.py """ HOST=‘127.0.0.1‘ PORT=3306
1 # staticmethod与classmethod的区别 2 import settings 3 class MySQL: 4 def __init__(self,host,port): 5 self.host=host 6 self.port=port 7 @classmethod #绑定到类,如果这里使用的是staticmethod ,就会执行父类的__str__,打印 就不告诉你 8 def from_conf(cls): #from_conf(Mariab) 9 return cls(settings.HOST,settings.PORT) #Mariab(settings.HOST,settings.PORT) 10 11 def __str__(self): 12 return "就不告诉你" 13 14 class Mariab(MySQL): 15 def __str__(self): 16 return ‘host:%s port:%s‘ %(self.host,self.port) 17 18 conn1=Mariab.from_conf() 19 print(conn1) #打印对象时自动执行 __str__方法,先找自己,所以打印出host:127.0.0.1 port:3306 20 21 22 """ 23 输出: 24 host:127.0.0.1 port:3306 25 """
七、反射
查看参数一类中有没有参数二的属性
1 class Chinese: 2 country=‘China‘ 3 def __init__(self,name,age): 4 self.name=name 5 self.age=age 6 7 # print(Chinese.county) #Chinese.__dict__[‘country‘] 8 9 p=Chinese(‘egon‘,18) 10 # print(p.name) #p.__dict__[‘name‘] 11 # 12 print(hasattr(p,‘name‘)) 13 print(hasattr(Chinese,‘country‘)) 14 15 """ 16 输出: 17 True 18 True 19 """
查看类中属性的值,存在则显示,不存在显示第三个参数默认值
1 p.x=1 2 print(p.__dict__) 3 print(p.x) 4 setattr(p,‘x‘,1231231231231) 5 print(p.__dict__) 6 print(p.x) 7 8 9 print(getattr(p,‘x‘,‘not exist‘)) 10 print(getattr(p,‘name‘,‘not exist‘)) 11 12 """ 13 输出: 14 {‘name‘: ‘egon‘, ‘age‘: 18, ‘x‘: 1} 15 1 16 {‘name‘: ‘egon‘, ‘age‘: 18, ‘x‘: 1231231231231} 17 1231231231231 18 1231231231231 19 egon 20 """
获取当前模块
1 import sys 2 m=sys.modules[__name__] 3 print(m)
反射例子:
1 """ 2 ftpclient.py 3 """ 4 5 class FtpClient: 6 ‘ftp客户端,但是还么有实现具体的功能‘ 7 def __init__(self,addr): 8 print(‘正在连接服务器[%s]‘ %addr) 9 self.addr=addr 10 11 def get(self): 12 print(‘is getting‘)
1 """ 2 ftp.py 3 """ 4 5 class FtpCLient: 6 def __init__(self,host): 7 self.host=host 8 print(‘connecting...‘) 9 10 def run(self): 11 while True: 12 inp=input(‘>>: ‘).strip() 13 inp_l=inp.split() 14 if hasattr(self,inp_l[0]): 15 func=getattr(self,inp_l[0]) 16 func(inp_l) 17 18 def get(self,arg): 19 print(‘download file‘,arg[1]) 20 21 f=FtpCLient(‘192.168.1.2‘) 22 # f.run() 23 24 25 # m=__import__(‘sys‘) 26 # print(m) 27 # import importlib 28 # m=importlib.import_module(‘sys‘) 29 # print(m) 30 31 32 property
1 # import ftpclient 2 # f1=ftpclient.FtpClient(‘192.168.1.1‘) 3 # 4 # if hasattr(f1,‘get‘): 5 # func=getattr(f1,‘get‘) 6 # func() 7 # 8 # print(‘其他的代码1‘) 9 # print(‘其他的代码2‘) 10 # print(‘其他的代码3‘) 11 # print(‘其他的代码3‘) 12 # print(‘其他的代码4‘) 13 # print(‘其他的代码5‘) 14 # print(‘其他的代码6‘)
面向对象-day07