云顶娱乐平台 9

【云顶娱乐平台】面向对象进阶

class Foo(object):
    pass

class Bar(Foo):
    pass

issubclass(Bar, Foo)

     
从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。

                             
a、在python中用双划线的开头的的方式降属性隐藏起来(设置私有的)

      并且使用str的返回值;如果没有__云顶娱乐平台,str__,那么print, %s,
str都会执行repr

class Person:   #定义一个人类
    role = 'person'  #人的角色属性都是人
    def walk(self):  #人都可以走路,也就是有一个走路方法
        print("person is walking...")


print(Person.role)  #查看人的role属性
print(Person.walk)  #引用人的走路方法,注意,这里不是在调用

  获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值

     13、类命名空间与对象、实例的命名空间

  3.
在python中,并没有接口类这种东西,即便不通过专门的模块定义接口,我们也应该有

        b、内置方法:issubclass(sub, super)检查sub类是否是
super 类的派生类 

   1.开辟一个空间,属于对象的  2.
把对象空间传给self,执行init,封装属性

创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性

class A: pass

class B(A): pass

abj = B()

print(issubclass(B,A)) #True  #判断类的继承关系

           b、封装

  6. 方法的实现

class Person:   #定义一个人类
    role = 'person'  #人的角色属性都是人
    def __init__(self,name):
        self.name = name  # 每一个角色都有自己的昵称;

    def walk(self):  #人都可以走路,也就是有一个走路方法
        print("person is walking...")


print(Person.role)  #查看人的role属性
print(Person.walk)  #引用人的走路方法,注意,这里不是在调用

 

python自带多态:

  多态:同一类事物的多种状态

  python里处处都是多态,只是我们一般发现不了

  操作的时候不需要关心这个对象的数据类型,你只要用就行了

  6. getattr(object, name[default])  

class Foo:
    pass
class Son(Foo):
    pass
s=Son()

print(isinstance(s,Son))
class C:

    __name = "私有静态字段"

    def func(self):
        print C.__name

class D(C):

    def show(self):
        print C.__name


C.__name       # 不可在外部访问

obj = C()
obj.__name  # 不可在外部访问
obj.func()     # 类内部可以访问   

obj_son = D()
obj_son.show() #不可在派生类中可以访问  

property属性

 

    8、类的两种作用:属性引用和实例化

class Foo:

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

obj1 = Foo('wupeiqi', 18)
print obj1.name    # 直接调用obj1对象的name属性
print obj1.age     # 直接调用obj1对象的age属性

obj2 = Foo('alex', 73)
print obj2.name    # 直接调用obj2对象的name属性
print obj2.age     # 直接调用obj2对象的age属性

property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值

  1.
封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。

               isinstance(obj,cls)检查是否obj是否是类 cls
的对象

class A :
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __eq__(self,other):
        if self.name == other.name and self.age == other.age:
            return True

a = A('小白',88)
aa = A('大白'99)
aaa = A('超大白',100)

print(a,aa)
print(a == aa == aaa)     # == 这个语法是完全和__eq__相关

面相对象的组合用法:

   1>  对于每一个类的成员而言都有两种形式:

                  3、私有变量和私有方法

   的类,它的特殊之处在于只能被继承,不能被实例化

         
 c、多态:”多态指的是一类事物有多种形态(比如:老师.下课铃响了(),学生.下课铃响了(),老师执行的是下班操作,学生执行的是放学操作,虽然二者消息一样,但是执行的效果不同)

   值的结果不一样.

  

    奥迪,还是大众我们都会开了,开的时候根本无需关心我开的是哪一类车,操作

     
 b、缺点:可控性差,无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就有对象之间的交互解决问题。

    getattr (空间名 , ‘空间内的变量’)  可以看做是对
空间名.空间内的变量 进行替换

                  1、优点:

  1. 什么是抽象类

 

  2.
实践中,继承的第一种含义意义并不很大,甚至常常是有害的。因为它使得子类与基

检查是否含有某属性---hasattr 返回布尔值
获取属性---getattr   没有就会报错
设置属性---setattr
删除属性---delattr

 

               delattr:删除该对象指定的一个属性

 

          a、内置方法:isinstance和issubclass

 

           b、而类有两种属性:静态属性和动态属性

class A:
    def __init__(self):
        pass
    def __str__(self):
        return '白'
a = A()
print(a)    #相当于调用a的__str__方法
print('%s' % a)#相当于执行a.__str__方法

另:print(str(obj))  #内置的数据类型相当于执行obj.__str__方法

     
 a、优点:极大的降低了写程序的复杂度,只需要顺着执行的步骤,堆叠代码即可

class A:
    def func(self):# 普通方法
        print(self)

    @classmethod    #类方法
    def func1(cls)
        print(cls)


a = A()
a.func()    #对象调用的普通方法
A.func(a)    #类名调用的普通方法

A.func1()  #类方法:通过类名调用的方法,类方法中第一个参数约定俗成是 cls
                        #python自动将类名(类空间)传给 cls    

           a、继承

 

                              d、提高安全性

 

一、面向对象

    类名反射 : 静态属性  类方法  静态方法

     
 b、缺点:一套流水线或者流程就是来解决一个问题,代码就是牵一发而东莞全身

   所以,在使用面向对象的封装特性时,需要:

                  2、封装原则:

 

                
需要注意的是,如果返回的是对象的方法,返回出来的是对象的内存地址,如果需要运行这个方法,可以在后面添加一对()

 

   1、面向过程

   构造方法  :__new__

   4、对象/实例:具体的某一个事物(隔壁阿花、楼下旺财)

      import sys   mymodule =
[‘__main__’]   getattr(mymodule.’变量名’)

from  math  import pi
class Circular:
    def __init__(self,radius):
        self.radius=radius
    def area(self):
        return self.radius **2 * pi
    def perimeter(self):
        return 2 * self.radius * pi
circu=Circular(10)
print(circu.area())
print(circu.perimeter())

  1. 继承有两种用途  

   6、
在python中,用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是‘类’,

class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __len__(self):
        return len(self.__dict__)  #__len__方法return的值就是len函数的返回值
a = A()
print(len(a))  #len(obj)相当于调用了这个对象的__len__方法,如果obj对象没有__len__方法
            那么len函数就会报错

               setattr:给对象的属性赋值,若属性不存在,先创建后赋值

   3>
 接口提取了一群类共同的函数,可以把接口当做一个函数的集合。
然后让子

python2
class Dad:  #经典类
class Dag(object)  #新式类

python3
class Dad  ==  class Dag(object) #新式类

    __getitem__

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

 

             
 hasattr:hasattr(object,name)判断一个对象是否有name属性或者name方法。有就返回True,没有就返回False

     (3),
继承中,父类得到子类的空间(子类类名调用,类名传给cls,父类中则会得到子类地址)

     
 a、优点:解决程序的扩展性,对某一个对象单独修改,会立刻反应到整个体系中

   hash是一个算法能够把某一个要存在内存里的值通过一系列计算,保证不同值hash

                   多态指的是:一类实物有多种状态

  9. hash方法

class Foo:
    def __del__(self):
        print('fgs')
f=Foo()
print(123)
print(123)
del f
print(123)
print(123)
print(123)

issubclass(sub, super)检查sub类是否是 super 类的派生类

        2、反射有四种方法:

  

                              a、将不需要对外提供的内容都隐藏起来

 

   2、面向对象

    在继承抽象类的过程中,我们应该尽量避免多继承;
    而在继承接口的时候,我们反而鼓励你来多继承接口

 

三, 多态

__getitem____setitem____delitem__

    __new__

class A:
    def __init__(self):  #有一个方法在帮你创造self
        print('in init function')
        self.x=1
    def __new__(cls, *args, **kwargs):
        print('in init funct')
        return object.__new__(A,*args,**kwargs)
a=A()

     f、__str__和__repr__改变对象的字符串显示

云顶娱乐平台 1云顶娱乐平台 2

class Foo:
 2     def __init__(self,name):
 3         self.name = name
 4     def __repr__(self):
 5         return 'obj in str'  #这里只能是return
 6     # def __str__(self):
 7     #     return '%s obj in str'%self.name
 8 f = Foo('egon')
 9 print(f)  #优先执行__str__里面的内容
10 # 那么你是不是据地__repr__没用呢?
11 # print('%s'%f)  #执行的是__str__里面的返回值
12 # print('%r'%f)  #执行的是__repr__里面的返回值
13 print('==============')
14 print(str(f))  #当执行str(f)时,会去找__str__这个方法,如果找不到的时候,__repr__这个方法就给替补了
15 print(repr(f))
16 #1.当打印一个对象的时候,如果实现了__str__方法,打印__str__中的返回值
17 # 2.当__str__没有被实现的时候,就会调用__repr__方法
18 # 3.但是当你用字符串格式化的时候,%s和%r会分别调用__str__和__repr__方法
19 # 4.不管是在字符串格式化的时候还是在打印对象的时候,
20 # __repr__方法都可以作为__str__方法的替补,但反之则不行
21 # 5.用于友好的表示对象。如果__str__和__repr__方法你只能实现一个:先实现__repr__

__str__,__repr__

    15、内置方法

           a、静态方法和类方法

             
 1、类方法:有个默认参数cls,并且可以直接用类名去调用,可以与类属性交互(也就是可以使用类属性)

             
 2、静态方法:让类里的方法直接被类调用,就像正常调用函数一样

           b、类方法和静态方法的相同点:都可以直接被类调用,不需要实例化

           c、类方法和静态方法的不同点:

          类方法必须有一个cls参数表示这个类,可以使用类属性

           静态方法不需要参数

           d、绑定方法:分为普通方法和类方法

     普通方法:默认有一个self对象传进来,并且只能被对象调用——-绑定到对象

     类方法:默认有一个cls对象传进来,并且可以被类和对象(不推荐)调用—–绑定到类

           
e、非绑定方法:静态方法:没有设置默认参数,并且可以被类和对象(不推荐)调用—–非绑定

    16、接口类与抽象类

             a、 接口类:(在抽象类的基础上)

         在python中,默认是没有接口类的           

                    接口类不能被实例化(如果实例化会报错)

          接口类中的方法不能被实现

接口也就是做约束,让下面的类的方法都按照接口类中给出的方法去定义。如果接口类里面有的方法类里面没有,那么那个类就不能被实例化。(字面理解)

继承的第二种含义非常重要。它又叫“接口继承”。
接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。

           b、抽象类

在python中,默认是有的

    父类的方法,子类必须实现

    抽象类(父类)的方法可以被实现

抽象类和接口类的区别:接口类不能实现方法,抽象类可以实现方法里面的内容

抽象类和接口类的相同点:都是用来做约束的,都不能被实例化

抽象类和接口类的使用:

  当几个子类的父类有相同的功能需要被实现的时候就用抽象类

  当几个子类有相同的功能,但是实现各不相同的时候就用接口类

 

class  A :
    @staticmethod
    def func(self):
        print(33)

A.func()
#结果: 33

       

    •  将内容封装到某处
    •  从某处调用被封装的内容

                 
a:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义

   抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以

类名
    类名.类属性
   类名.方法名

实例 = 类名(参数,参数)  #实例就是对象

实例
    实例.方法名()
   实例.对象属性

实例增加属性
实例.新的属性名 = 1000
print(实例.新的属性名)

云顶娱乐平台 3

         
 a、常见一个类就会创建一个类的名称空间,用来储存类中定义的所有名字,这些名字成为类的属性

 

       d、内置方法:__del__

  7. setattr(object, name, values)

        1、
反射:可以用字符串的方式去访问对象的属性,调用对象的方法(但是不能去访问方法),python中一切皆对象,都可以使用反射。

   做出针对性的设计:细致到什么程度,视需求而定)。

云顶娱乐平台 4云顶娱乐平台 5

  1.  如下面的图所示:面向对象整体大致分两块区域:

圆的周长与面积

   

                              c、提高复用性

  1.
Pyhon不支持Java和C#这一类强类型语言中多态的写法,但是原生多态,其Python崇尚

                       
 **
 了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能**

import sys


def s1():
    print('s1')


def s2():
    print('s2')

this_module = sys.modules[__name__] 

hasattr(this_module, 's1') 
getattr(this_module, 's2')

             
getattr:获取对象的属性或者方法,如果存在则打印出来。hasattr和getattr配套使用

  1.
封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的

   12、关于self

 

    11、

 

析构方法,当对象在内存中被释放时,自动触发执行。

   象linux的泛文件概念一样,所有东西都可以当文件处理,不必关心它是内存、磁盘、

                 
b:继承基类的方法,并且做出自己的改变或者扩展(代码重用)***
  ***

    应用场景:

                              a、将变化隔离

  10. eq 方法

class Animal:      #父类  基类  超类
    def __init__(self,name,life_value,aggr):
        self.name = name
        self.life_value = life_value
        self.aggr = aggr


class Person(Animal):  #子类  派生类
    pass

class Dog(Animal): #子类  派生类
    pass

egg = Person('egon',1000,50)
print(egg.name)
print(egg.aggr

 

    9、属性引用(类名.属性)

     
名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能

self:在实例化时自动将对象/实例本身传给__init__的第一个参数,你也可以给他起个别的名字.

对象/实例只有一种作用:属性引用

class 类名:
    def __init__(self,参数1,参数2):
        self.对象的属性1 = 参数1
        self.对象的属性2 = 参数2

    def 方法名(self):pass

    def 方法名2(self):pass

对象名 = 类名(1,2)  #对象就是实例,代表一个具体的东西
                  #类名() : 类名+括号就是实例化一个类,相当于调用了__init__方法
                  #括号里传参数,参数不需要传self,其他与init中的形参一一对应
                  #结果返回一个对象
对象名.对象的属性1   #查看对象的属性,直接用 对象名.属性名 即可
对象名.方法名()     #调用类中的方法,直接用 对象名.方法名() 即可

dir(类) #返回类中的所有名字列表
isinstance(对象,类) #判断对象是否为类的实例
print(Person.__dict__) # 返回一个字典 key是属性名,value是属性值
print(Person.__module__)  #person类所在的模块
print(Person.__name__,type(Person.__name__)) #字符串数据类型的类名

   对通一个值多次执行的python代码的时候hash值的结果是不同的,但是对通一个值

   7、对象是则是这一类事物中具体的一个

  2. 面向对象的公有私有 

                              b、封装使用

  将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name

   5、实例化:类——>对象的过程

*  1>
property是
一*种特殊的属性,访问它时会执行一段功能(函数)然后返回值

     e、内置方法:item系列

 

              1、继承的语法

# 一:这样不好,我要统一一下支付的规则.

class QQpay:
    def pay(self,money):
        print('使用qq支付%s元' % money)

class Alipay:
    def pay(self,money):
        print('使用阿里支付%s元' % money)

a = Alipay()
a.pay(100)

b = QQpay()
b.pay(200)


# 二,统一支付的规则 归一化设计,统一 pay接口
class QQpay:
    def pay(self,money):
        print('使用qq支付%s元' % money)

class Alipay:
    def pay(self,money):
        print('使用阿里支付%s元' % money)

def pay(obj,money):        
    obj.pay(money)        #统一调用上面类中pay方法,

a = Alipay()
b = QQpay()

pay(a,100)
pay(b,200)


# 三,但是,来了一个野生程序员,他不知道你的约定俗成的规则,就会出问题

class QQpay:
    def pay(self,money):
        print('使用qq支付%s元' % money)

class Alipay:
    def pay(self,money):
        print('使用阿里支付%s元' % money)

class Wechatpay:
    def fuqian(self,money):
        print('使用微信支付%s元' % money)

def pay(obj,money):
    obj.pay(money)

a = Alipay()
b = QQpay()

pay(a,100)
pay(b,200)

c = Wechatpay()
c.fuqian(300)


# 四,解决方式
# 定义一个父类,什么都不写,只是要求继承我的所有类有一个pay方法,这样就制定了一个规范,这就叫做接口类,后者抽象类.
class Payment:
    def pay(self):pass

class QQpay(Payment):
    def pay(self,money):
        print('使用qq支付%s元' % money)

class Alipay(Payment):
    def pay(self,money):
        print('使用阿里支付%s元' % money)

class Wechatpay(Payment):
    def fuqian(self,money):
        print('使用微信支付%s元' % money)


def pay(obj,money):
    obj.pay(money)

a = Alipay()
b = QQpay()

pay(a,100)
pay(b,200)

c = Wechatpay()
c.fuqian(300)

#五,他还是不知道看你这些都继承了一个类,所以你要制定一个规范,强制他执行.
# 创建一个规范
from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta):    # 抽象类 接口类  规范和约束  metaclass指定的是一个元类
    @abstractmethod
    def pay(self):pass  # 抽象方法

class Alipay(Payment):
    def pay(self,money):
        print('使用支付宝支付了%s元'%money)

class QQpay(Payment):
    def pay(self,money):
        print('使用qq支付了%s元'%money)

class Wechatpay(Payment):
    # def pay(self,money):
    #     print('使用微信支付了%s元'%money)
    def recharge(self):pass

def pay(a,money):
    a.pay(money)

a = Alipay()
a.pay(100)
pay(a,100)    # 归一化设计:不管是哪一个类的对象,都调用同一个函数去完成相似的功能
q = QQpay()
q.pay(100)
pay(q,100)
w = Wechatpay()
pay(w,100)   # 到用的时候才会报错



# 抽象类和接口类做的事情 :建立规范
# 制定一个类的metaclass是ABCMeta,
# 那么这个类就变成了一个抽象类(接口类)
# 这个类的主要功能就是建立一个规范    
class Person:   #定义一个人类
    role = 'person'  #人的角色属性都是人
    def walk(self):  #人都可以走路,也就是有一个走路方法,也叫动态属性
        print("person is walking...")

class 类名:
    类属性 = None
    def __init__(self,对象属性):
        self.对象属性 = 对象属性

    def 方法名(self):
        pass

实例 = 类名(10)
实例.方法名()

  3> 单例类

    15、反射     

云顶娱乐平台 6

   3、 类:具有相同特征的一类事物(人、狗、老虎)

二,  抽象类

     
 c、python面向对象中的反射:通过字符串的形式操作对象相关的属性,python中一切事物都是对象(都可以用反射)

 

              2、继承的两种用途:                

class B:
  #def __init__(self,lis):
    #self.lis = lis
  def __getitem__(self,item):
    return  getattr(self,item)
    #return self.lis[litem]
  def __setitem__(self,key,value):
    setattr(self,key,value)
    #self.lis[key] = vslue
  def __delitem__(self,key):
    delattr(self,key)
    #self.lis.pop(key)

b = B()

b['k'] = 'v1'  #触发__setitem__
print(b['k1']) #  __getitem__
del b['k1']   #  __delitem__

#b = B(['11','22','33','44'])
#print(b.lis[0])
#B[3] = '99'
#print(b.list)
#del b[2]
#print(b.lis)

 

    1> __repr__ 是__str
__的备胎,如果有__str__方法,那么 print, %s,  str 都去执行str方法,

                              b、把属性都隐藏起来提供公共方法对其访问

  

  •  静态属性就是直接在类中定义的变量
  • 动态属性就是定义在类中的方法

 

     14、面向对象的三大特征

  由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方

 class 类名(父类名):
      想在子类中实现调用父类的方法
      在类内 ——super(子类名,self).方法名()
      在类外面 ——super(子类名,对象名).方法名()
      如果不指定继承的父类,默认继承object
      子类可以使用父类的所有属性和方法
      如果子类有自己的方法就执行自己的的
      如果是子类没有的方法就执行父类的
      如果子类父类都没有这个方法就报错

继承、抽象、派生
继承 是从大范围到小范围
抽象 小范围到大范围
派生 就是在父类的基础上又产生子类——派生类
        父类里没有的 但子类有的 ——派生方法
        派生属性
方法的重写
    父类里有的方法,在子类里重新实现

 

 

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组

    优点: 1. 代码块清晰  2. 增加复用性  

   
10、例化:类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征

   
从实现角度来看,抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被

列子:

class A:
    __instance = None
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:#不空则执行下面程序,若为空则不执行,即只开辟一次空间
           cls.__instance=object.__new__(cls)#调用object类中的__new__方法,开辟一个空间
        return cls.__instance#返回空间地址
    def __init__(self,name,age):#把空间地址传给self
        self.name=name
        self.age=age

s1=A('he',23)
s2=A('ha',30)#返回的还是第一次开辟的空间,只是s2的属性将会覆盖原来的属性
print(s1.name)
print(s2.name)
#结果:  ha ha

      2> 私有成员和公有成员的访问限制不同:

  

*     *
与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊

   一些基本的概念。

  如果一个类中定义了__str__方法,那么在打印 对象
时,默认输出该方法的返回值.

   
比如我们有香蕉的类,有苹果的类,有桃子的类,从这些类抽取相同的内容就是水果这

  法定义为对同一个属性:获取、修改、删除

   程序设计上,叫做归一化。

 

   初始化方法: __init__

    类去实现接口中的函数。
这么做的意义在于归一化,什么叫归一化,就是只

一,.接口类

   2>
注意:在python中根本就没有一个叫做interface的关键字,上面的代码只是看起来像

C.name         # 类访问

obj = C()
obj.func()     # 类内部可以访问

obj_son = D()
obj_son.show() # 派生类中可以访问

  首先找到自己当前文件所在的命名空间

  

   网络还是屏幕(当然,对底层设计者,当然也可以区分出“字符设备”和“块设备”,然后

  5. 对其他模块反射

  2. 抽象类与接口类

   个抽象的类,你吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子,你永远

   调用被封装的内容时,有两种情况:

    自己模块中:

class F1:
    pass


class S1(F1):

    def show(self):
        print 'S1.show'


class S2(F1):

    def show(self):
        print 'S2.show'


# 由于在Java或C#中定义函数参数时,必须指定参数的类型
# 为了让Func函数既可以执行S1对象的show方法,又可以执行S2对象的show方法,所以,定义了一个S1和S2类的父类
# 而实际传入的参数是:S1对象和S2对象

def Func(F1 obj):
    """Func函数需要接收一个F1类型或者F1子类的类型"""

    print obj.show()

s1_obj = S1()
Func(s1_obj) # 在Func函数中传入S1类的对象 s1_obj,执行 S1 的show方法,结果:S1.show

s2_obj = S2()
Func(s2_obj) # 在Func函数中传入Ss类的对象 ss_obj,执行 Ss 的show方法,结果:S2.show

Python伪代码实现Java或C#的多态

Python伪代码实现java C#多态

#鸭子类型

class F1:
    pass


class S1(F1):

    def show(self):
        print 'S1.show'


class S2(F1):

    def show(self):
        print 'S2.show'

def Func(obj):
    print obj.show()

s1_obj = S1()
Func(s1_obj) 

s2_obj = S2()
Func(s2_obj) 

#都有同样的方法,使用上类似,具有统一化设计思想,就叫鸭子类型
import sys

def s1():
    print('s1')

def s2():
    print('s2')

 this_module = sys.modules[__name__]#获取当前模块的空间地址

hasattr(this_module, 's2')
getattr(this_module, 's2')

云顶娱乐平台 7

class A :    
    def __del__(self):   #析构方法 del A的对象 会自动触发这个方法 
        print('饿了吗')
a = A()
del a    #对象删除 del    当不主动进行该操作时,python解释器在程序执行
                #完后也会自动触发 __del__ 函数(垃圾回收机制).
print(a)        

  4. 对当前模块反射

    hasattr : 判断类中是否存在要调用的变量或方法

    

 

    鼠的类去实现了该接口,松鼠的类也去实现了该接口,由二者分别产生一只老鼠

   触发这些内置方法

  

   同的.

   getattr  hasattr  setattr  delattr

   内置函数和内置方法是有密切联系的

 

 

      __repr__方法,如果子类也没有,还要向上继续找父类中的__repr__方法,一直找不到

  2. 为什么要有抽象类

    法上来说都一样。
归一化,让使用者无需关心对象的类是什么,只需要的知道

   代码永远无需改变。这就提供一个良好的合作基础——或者说,只要接这个基础约定

  1> 通过对象直接调用被封装的内容

class A: pass

class B(A): pass

obj = B()
print(isinstance(obj,B))  #True  判断对象所属关系,包含所有继承关系,只要是
print(isinstance(obj,str))  #True
print(type(obj) is str)     #不包含继承系,只管一层

    手法(函数调用)都一样

五, 封装性与扩展性

   再痛一次执行python代码的时候hash值永远不变. 

 

   执行是由对象后加括号触发的,即:对象() 或者 类()()

 

  3. 第二步:从某处调用被封装的内容

  可选。需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行

云顶娱乐平台 8

例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)

成人的BMI数值:
过轻:低于18.5
正常:18.5-23.9
过重:24-27
肥胖:28-32
非常肥胖, 高于32
  体质指数(BMI)=体重(kg)÷身高^2(m)
  EX:70kg÷(1.75×1.75)=22.86

class People:
    def __init__(self,name,weight,height):
        self.name=name
        self.weight=weight
        self.height=height
    @property
    def bmi(self):
        return self.weight / (self.height**2)

p1=People('egon',75,1.85)
print(p1.bmi)
>>> class test():
...     name="xiaohua"
...     def run(self):
...             return "HelloWord"
...
>>> t=test()
>>> hasattr(t, "age")   #判断属性是否存在
False
>>> setattr(t, "age", "18")   #为属相赋值,并没有返回值
>>> hasattr(t, "age")    #属性存在了
True
>>>

      接口,其实并没有起到接口的作用,子类完全可以不用去实现接口 

     2>
在子类中使用__str__,先找子类的__str__,没有的话要向上找,只要父类不是object,就

   中,然后通过对象直接或者self间接获取被封装的内容

  4.  __str__

     (1), 类中有些方法是不需要传入对象,不要对象的一切东西

 

  1.
python面向对象中的反射:通过字符串数据类型的变量名来访问这个变量的值。python

 

class Employee:
    def __init__(self,name,age,sex,partment)
        self.name=name
        self.age=age
        self.sex = sex
        self.partment = partment
    def__hash__(self):            #筛选hash值相等
        return hash('%s%s' % (self.name,self.sex))
    def __eq__(self,other):        #筛选值相等
        if self.name == other.name and self.sex == other.sex
            return True
    employ_lst = [...]
    for i in range(200)
            employ_lst.append(Employee('alex',i,'male','python'))
     for i in range(200)
            employ_lst.append(Employee('wusir',i,'male','python'))  
    for i in range(200)
            employ_lst.append(Employee('taibai',i,'male','python'))    
employ_lst = set(employ_lst)
for person in employ set :
    print(person.__dic__ )


#set集合的去重原理

   上图展示了对象 obj1 和 obj2
在内存中保存的方式,根据保存格式可以如此调用被封

     1>  继承的第二种含义非常重要。它又叫“接口继承”。
    
 接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外

   用来实现归一化设计 

 

   类出现强耦合。

      repr(obj)  %r 

    对象反射 : 对象属性  方法  

  4. 多继承问题

   如果一个类,从头到尾只能有一个实例,说明只开辟一块属于对象的空间,那么这个类就是一

 

   “鸭子类型”

>>> class test():
...     name="xiaohua"
...     def run(self):
...             return "HelloWord"
...
>>> t=test()
>>> getattr(t, "name") #获取name属性,存在就打印出来。
'xiaohua'
>>> getattr(t, "run")  #获取run方法,存在就打印出方法的内存地址。
<bound method test.run of <__main__.test instance at 0x0269C878>>
>>> getattr(t, "run")()  #获取run方法,后面加括号可以将这个方法运行。
'HelloWord'
>>> getattr(t, "age")  #获取一个不存在的属性。
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: test instance has no attribute 'age'
>>> getattr(t, "age","18")  #若属性不存在,返回一个默认值。
'18'
>>>

   底层数据结构基于hash值寻址的优化操作

 

class Foo:

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

    def detail(self):
        print self.name
        print self.age

obj1 = Foo('wupeiqi', 18)
obj1.detail()  # Python默认会将obj1传给self参数,即:obj1.detail(obj1),所以,此时方法内部的 self = obj1,即:self.name 是 wupeiqi ;self.age 是 18

obj2 = Foo('alex', 73)
obj2.detail()  # Python默认会将obj2传给self参数,即:obj1.detail(obj2),所以,此时方法内部的 self = obj2,即:self.name 是 alex ; self.age 是 78

  那么每个大区域又可以分为多个小部分

 

class A:

    company_name = '老男孩教育'  # 静态变量(静态字段)
    __iphone = '1353333xxxx'  # 私有静态变量(私有静态字段)


    def __init__(self,name,age): #普通方法(构造方法)

        self.name = name  #对象属性(普通字段)
        self.__age = age  # 私有对象属性(私有普通字段)

    def func1(self):  # 普通方法
        pass

    def __func(self): #私有方法
        print(666)


    @classmethod  # 类方法
    def class_func(cls):
        """ 定义类方法,至少有一个cls参数 """
        print('类方法')

    @staticmethod  #静态方法
    def static_func():
        """ 定义静态方法 ,无默认参数"""
        print('静态方法')

    @property  # 属性
    def prop(self):
        pass

    要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用

 

  8. item 系列: 和对象使用 [ ] 访问值有联系

   归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合——就好

 

通过self间接调用被封装的内容

  2. 使用对象来反射:

 

   抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属

   不变,则代码改变不足为虑.

   实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不

 

  2>  __new__开辟空间,返回给self,
在实例化对象之后,__init__之前,执行__new__方法.

  2. __len__

  1. __call__  对象后面加括号,触发执行。

class Foo:

    def __init__(self):
        pass

    def __call__(self, *args, **kwargs):

        print('__call__')


obj = Foo() # 执行 __init__
obj()       # 执行 __call__

    getattr : 可与hasattr 结合使用,若hasattr判断存在,则执行 getattr.

  

  这个方法,可以在后面添加一对括号。

  2>:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口

  

   执行类中的方法时,需要通过self间接调用被封装的内容

 

 

  2. 将内容封装到某处

 
  
  5. 接口隔离原则:
  使用多个专门的接口,而不使用单一的总接口。即客户端不应该依赖那些不需要的接口。

七,  isinstance与issubclass

  4. 类方法:  @classmethod

  是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

九, 内置方法(双下划线方法,魔术方法,类中的特殊方法)

 

isinstance(obj,cls) 检查obj是否是类 cls 的对象

   无法吃到一个叫做水果的东西。

   装的内容:对象.属性名

 

   

      执行父类的__str__,但是如果出了object之外的父类都没有__str__方法,就执行子类的

 

                                   当执行 obj2 = Foo(‘alex’, 78 )
时,self 等于 obj2

  5. __repr__ :

  1>:继承基类的方法,并且做出自己的改变或者扩展(代码重用)  

  5. 静态方法:  @staticmethod

    和一只松鼠送到你面前,即便是你分别不到底哪只是什么鼠你肯定知道他俩都会

  给对象的属性赋值,若属性不存在,先创建再赋值.

 

 

   self 是一个形式参数,当执行 obj1 = Foo(‘wupeiqi’, 18 ) 时,self
等于 obj1

  在内存里类似于下图来保存。

   代码;而外部使用者只知道一个接口(函数),只要接(函数)名、参数不变,使用者的

    跑,都会吃,都能呼吸。
再比如:我们有一个汽车接口,里面定义了汽车所有

  3. 属性

    这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。

 

八,反射

    •  公有成员,在任何地方都能访问
    •  私有成员,只有在类的内部才能方法

 

 

      

    的功能,然后由本田汽车的类,奥迪汽车的类,大众汽车的类,他们都实现了汽

class Foo:
    f = '类的静态变量'
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def say_hi(self):
        print('hi,%s'%self.name)

obj=Foo('egon',73)

#检测是否含有某属性  若能找到返回True,找不到返回False
print(hasattr(obj,'name'))
print(hasattr(obj,'say_hi'))

#获取属性
n=getattr(obj,'name')
print(n)
func=getattr(obj,'say_hi')()

print(getattr(obj,'aaaaaaaa','不存在啊')) #报错

#设置属性
setattr(obj,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__)
print(obj.show_name(obj))

#删除属性
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111')#不存在,则报错

print(obj.__dict__)
    • 通过对象直接调用
    • 通过self间接调用

   部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在

 云顶娱乐平台 9

 

     __名字__  类中的每一个双下划线方法都有他自己的特殊意义

     (2), 对类中的静态变量进行改变

    静态字段(静态变量)

class Foo(object):

    staticField = "old boy"

    def __init__(self):
        self.name = 'wupeiqi'

    def func(self):
        return 'func'

    @staticmethod
    def bar():
        return 'bar'

print (getattr(Foo, 'staticField'))#调用静态字段 结果为 : old boy
print (getattr(Foo, 'func'))#调用函数,打印的是内存地址
print (getattr(Foo, 'bar')())#调用静态函数,结果为 : bar

  3.__new__

    归还/释放一些在创建对象的时候借用的一些资源

     注:__init__方法的执行是由创建对象触发的,即:对象 = 类名()
;而对于 __call__ 方法的

 

    车接口,这样就好办了,大家只需要学会了怎么开汽车,那么无论是本田,还是

class Goods(object):

    def __init__(self):
        # 原价
        self.original_price = 100
        # 折扣
        self.discount = 0.8

    @property    #将该方法伪装成一个属性,在代码级别上没有本质的提升,但是让其看起来很合理.
    def price(self):
        # 实际价格 = 原价 * 折扣
        new_price = self.original_price * self.discount
        return new_price

    @price.setter  #固定写法, 其中伪装的函数属性名,要修改的方法属性名和 @属性名.setter 要一致
    def price(self, value):
        self.original_price = value

    @price.deltter
    def price(self, value):
        del self.original_price

obj = Goods()
obj.price         # 获取商品价格
obj.price = 200   # 修改商品原价
del obj.price     # 删除商品原价

  所以,内容其实被封装到了对象 obj1 和 obj2 中,每个对象中都有 name 和
age 属性,

    模块  :  模块中的方法

   所有的内置方法不需要再外部直接调用,而是用一些其它的内置函数或特殊的语法来自动

      再执行object类中的__str__的方法

    释放一个空间

六, 面向对象结构分析

    如:我们定义一个动物接口,接口里定义了有跑、吃、呼吸等接口函数,这样老

  1>  面向对象在实例化时:

class SIngle:
        def __new__(cls,*args,**kwargs):
                print('在new方法里')
                obj=object.__new__(cls)
                print('在new方法里',obj)
                return  obj
         def __init__(self):
               print('在init方法里',self)

obj=SIngle()

 

 

  2> 为什么要用property

 

  4.
综上所述,对于面向对象的封装来说,其实就是使用构造方法将内容封装到
对象

四, 封装

    个单例类

    •  公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
    •  私有静态字段:仅类内部可以访问;

    class C:

    name = "公有静态字段"
    
    def func(self):
        print C.name
    

    class D(C):

    def show(self):
        print C.name
    

   在抽象类中,我们可以对一些抽象方法做出基础实现;
   而在接口类中,任何方法都只是一种规范,具体的功能需要子类实现

  11. 析构方法  

   如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类是从一堆中抽取相同

 

   性(如read、write),而接口只强调函数属性的相似性

#类的设计者
class Room:
    def __init__(self,name,owner,width,length,high):
        self.name=name
        self.owner=owner
        self.__width=width
        self.__length=length
        self.__high=high
    def tell_area(self): #对外提供的接口,隐藏了内部的实现细节,此时我们想求的是面积
        return self.__width * self.__length


#使用者
>>> r1=Room('卧室','egon',20,20,20)
>>> r1.tell_area() #使用者调用接口tell_area


#类的设计者,轻松的扩展了功能,而类的使用者完全不需要改变自己的代码
class Room:
    def __init__(self,name,owner,width,length,high):
        self.name=name
        self.owner=owner
        self.__width=width
        self.__length=length
        self.__high=high
    def tell_area(self): #对外提供的接口,隐藏内部实现,此时我们想求的是体积,内部逻辑变了,只需求修该下列一行就可以很简答的实现,而且外部调用感知不到,仍然使用该方法,但是功能已经变了
        return self.__width * self.__length * self.__high


#对于仍然在使用tell_area接口的人来说,根本无需改动自己的代码,就可以用上新功能
>>> r1.tell_area()

  注意:对象调用类方法,cls 得到的是类本身

 

 

  3. 实用类来反射:

   3. 将这个对象空间返回给调用者

   中的一切事物都是对象(都可以使用反射)

   的内容而来的,内容包括数据属性和函数属性。

class A:
    def __init__(self,name):
        self.name=name
    def __str__(self):
        return '**%s**' % self.name
    def __repr__(self):
        return self.name
a = A('alex')
print(a)
print(str(a),repr(a))
print('%s , %r' % (a,a))


#注意:
# %r : 把 repr 的返回结果给 %r;
# %s :把 str 的返回结果给 %s