python面向对象之类成员

面向对象编程:

  OOP编程是利用类和对象来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得简单,并可以大大提高程序开发效率。另外,基于面向对象的程序可以使他人更容易理解代码逻辑,从而使团队开发变得更容易。

Class类:

  一个类即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化成多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人指具体的对象,人与人之间有共性亦有不同。

Encapsulation封装:

  在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊容器,里面包含着类的数据和方法。

Inheritance继承:

  一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承。

Polymorphism多态:

  多态是面向对象的重要特性,简单说:‘一个接口,多种实现’。指一个基类中派生出了不同的子类,且每个子类在继承同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。

  编程其实就是一个将具体世界进行抽象化得过程,多态就是抽象化得一种体现,把一系列具体事物的共同点抽象出来,再通过这个抽象的事物,与不同的具体事物进行对话。

  对不同类的对象发出相同的消息将会有不同的行为。比如,你的老板让所有员工再九点钟开始工作,他只要在九点钟的时候说开始工作即可,而不需要对销售人员说开始销售工作,对技术人员说开始技术工作。因为员工是一个抽象的事物,只要是员工就可以开始工作,他知道这一点就行了。至于每个员工,当然各司其职。

  多态允许将子类的对象当作父类的对象使用,某父类的引用指向其子类的对象,调用方法是该子类的方法。这里引用调用方法的代码编译前就已经决定了,而引用所指向的对象可以在运行期间动态绑定。

面向对象:

  面向对象是一种编程方式,此编程方式的实现是基于对类和对象的使用

  类是一个模板,模板中包装了多个函数供使用(可以将多函数中公用的变量封装到对象中)

  对象是根据模板创建的实例,实例用于调用被包装在类中的函数

  三大特性为:封装、继承、多态

类的成员可分为三大类:字段、方法和属性

  字段:普通字段、静态字段

  方法:普通方法、类方法、静态方法

  属性:普通属性

  PS:所有成员中,只有普通字段的内容保存在对象中,即,根据此类创建了多少对象,在内存中就有多少个普通字段。而其他的成员,则都是保存在类中,即无论对象的多少,在内存中只创建一份。

一、字段

  字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同。

  普通字段属于对象,静态字段属于类。

class Province(object):
    country = '中国'      #静态字段

    def __init__(self, name):
        self.name = name    #普通字段

obj = Province('山东')   #直接访问普通字段
print(obj.name)
print(Province.country) #直接访问静态字段

由上可看出普通字段需要通过对象来访问,静态字段通过类访问。在使用上可以看出普通字段和静态字段的归属是不同的,其在内容的存储方式类似如下:

由上图可以看出 静态字段在内存中只保存一份,普通字段在每个对象中都要保存一份

应用场景:通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段

二、方法:

方法包括:普通方法,静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。

  普通方法:由对象调用,至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self。

  类方法: 由类调用,至少一个cls参数;执行类方法时,自动将调用该方法的类赋值给cls。

  静态方法:由类调用,无默认参数。

class Foo(object):

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

    def ord_func(self):     #定义普通方法,至少需要self参数
        print('普通方法', self.name)

    @classmethod
    def cls_func(cls):      #定义类方法,至少需要cls参数
        print('类方法', cls)

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

obj = Foo('cab')
obj.ord_func()      #调用普通方法

Foo.cls_func()      #调用类方法

Foo.sta_func()      #调用静态方法

相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份

不同点:方法调用者不同,调用方法时自动传入的参数不同。

三、属性

1、属性的基本使用

class Foo(object):
    def func(self):
        print('func', self.prop)

    @property
    def prop(self):     #定义属性
        print('property')

obj = Foo()

obj.func()
obj.prop    #调用属性

由属性的定义和调用要注意以下几点:

  定义时,在普通方法的基础上添加property装饰器;属性仅有一个self参数;调用时,无需括号

  方法的调用:obj.func()   属性的调用:obj.prop

  属性的存在意义是:访问属性时可以制造出和访问字段完全相同的假象。属性由方法变种而来,如果python中没有属性,方法完全可以代替其功能。

示例: 对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示指定获取从第m条到第n条的所有数据(即:limit m,n),这个分页的功能包括:根据用户请求的当前页和总数据条数计算出m和n; 根据m和n去数据库中请求数据。

class Paper(object):
    per_item = 10       #定义每页显示的条数

    def __init__(self, current_page):
        self.current_page = current_page        #输入当前页数

    @property
    def start(self):
        value = (self.current_page - 1) * self.per_item + 1
        return value        #返回当前页的起始条
  def end(self):
        value = self.current_page * self.per_item
        return value        #返回当前页的结束条
  bar = property(end)
obj = Paper(2) print(obj.start) print(obj.bar)    #自动调用bar方法,并获取方法的返回值

由上述可见,python的属性的功能是:属性内部进行一系列的逻辑计算,最终将计算结果返回。

2、属性的两种定义方式:

  装饰器方式:即在方法上应用装饰器property

  静态字段方式:在类中定义值为property对象的静态字段。(比如上例中的bar对象)

装饰器方式:在类的普通方法上应用@property装饰器,在上例中应用的是经典类,即具有一种@property装饰器。

一下介绍一下新式类:

class Foo(object):
    @property
    def price(self):
        print('古典类property')

    @price.setter
    def price(self, value):
        print(value)

    @price.deleter
    def price(self):
        print('新式类之deleter')

    @price.getter
    def price(self):
        print('新式类之getter')
obj = Foo()
obj.price
#自动执行@price.getter修饰的price方法,并获取@price.getter方法的返回值
#如果没有@price.getter的修饰,则执行@property修饰的price方法,并返回


obj.price = 222
#自动执行@property修饰的price方法,并将222赋值给方法的参数

del obj.price #自动执行@price.deleter修饰的price方法
 

PS:经典类中的属性只有一种访问方式,其对应被@property修饰的方法。新式类中的属性由三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter、@方法名.getter修饰的方法

由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同意个属性:获取、修改、删除。

class Goods(object):
    def __init__(self, price, sale):
        self.old_price = price      #原价
        self.sale = sale            #折扣

    @property
    def cost(self):
        new_price = self.old_price * self.sale  #实际价格
        print('new_price:', new_price)
        return new_price

    @cost.setter
    def cost(self, price):
        self.old_price = price
        print(self.old_price)

    @cost.deleter
    def cost(self):
        del self.old_price

obj = Goods(100, 0.8)
obj.cost                #获取价格
obj.cost = 200          #定义价格
del obj.cost            #删除价格

静态字段方式,创建值为property对象的静态字段,当时用静态字段的方式创建属性时,经典类和新式类无区别。

class Foo(object):
    def get_bar(self):
        print('cab')
        return 111

    bar = property(get_bar)

obj = Foo()
res = obj.bar   #自动调用get_bar方法,并获取方法的返回值
print(res)

property的构造方法中有四个参数:

  • 第一个参数是方法名,调用 对象.属性 时自动触发执行方法
  • 第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法
  • 第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法
  • 第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息
class Foo(object):
    def get_bar(self):
        return 'cab'

    def set_bar(self, value):
        return value

    def del_bar(self):
        return 111

    BAR = property(get_bar, set_bar, del_bar, 'description...')

obj = Foo()

obj.BAR             #自动调用第一个参数中的get_bar方法
obj.BAR = 222       #自动调用第二个参数中的set_bar方法,并修改为222
del obj.BAR         #自动调用第三个参数中的del_bar方法
obj.BAR.__doc__     #自动获取第四个参数的值

定义属性由两种方式,分别是装饰器和静态字段,而装饰器方式针对经典类和新式类又有不同。

原文地址:https://www.cnblogs.com/caibao666/p/6634539.html