首页 > 代码库 > 面向对象-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