知行编程网知行编程网  2022-11-08 15:00 知行编程网 隐藏边栏  16 
文章评分 0 次,平均分 0.0
导语: 本文主要介绍了关于深入理解python面向对象-类成员的相关知识,包括python的理解,以及python面向对象详解这些编程知识,希望对大家有参考作用。

深入理解python面向对象——类成员

Python是一种面向对象的语言,但是由于python语言的特性,我们大部分的python程序员只是把它当成一个工具来使用。在我们项目的实际使用中,除了使用Django框架外,其余的都是最基本的使用python的方法,和pythonic完全没有关系,当然主要还是因为我们的能力比较差。面向对象是编写各种框架的基础。 Python 的面向对象不仅具有通用的面向对象的特性,而且还具有一些极其强大的特性,可以让我们最大限度地发挥它的便利性。本文将详细介绍Python类的成员、成员修饰符以及类的特殊成员。

类的成员

类的成员可以分为三个方面:字段、方法和属性。

定义一个类后,方法、属性和静态字段都属于该类,内存中只保存一份。只有普通字段属于类对象,每个类对象都会创建并保存一份。

我们可以将存储分为几种类型:程序存储、全局存储、静态存储和堆栈存储。

Program Memory:存储我们所有的普通函数、类函数、类等程序的位置。

全局存储区:所有全局变量的存储区。

静态存储区:类的静态变量存储区。

栈存储区:栈存储区是局部变量存储,所有的局部变量、类对象等都存放在这里。

字段

字段包括:常用字段和静态字段,它们的使用和定义不同。最本质的区别是内存中的位置。

普通字段属于对象

静态字段属于类

class Demo:
    aa = "我是静态字段"
    def __init__(self, name):
        self.bb = name    def custom_func(self, name):
        self.cc = name
obj1 = Demo(11)
Demo.aa = 111111obj1.aa = 1obj1.custom_func(1111)
obj2 = Demo(22)
obj2.aa = 2Demo.aa = 222222obj2.custom_func(2222)

print("obj1.aa = ", obj1.aa)
print("obj1.bb = ", obj1.bb)
print("obj1.cc = ", obj1.cc)
print("Demo.aa = ", Demo.aa)

print("obj2.aa = ", obj2.aa)
print("obj2.bb = ", obj2.bb)
print("obj2.cc = ", obj2.cc)
print("Demo.aa = ", Demo.aa)

print("id(Demo.aa) = ", id(Demo.aa))
print("id(obj1.aa) = ", id(obj1.aa))
print("id(obj2.aa) = ", id(obj2.aa))

输出

obj1.aa =  1
obj1.bb =  11
obj1.cc =  1111
Demo.aa =  222222
obj2.aa =  2
obj2.bb =  22
obj2.cc =  2222
Demo.aa =  222222
id(Demo.aa) =  4645988944
id(obj1.aa) =  4530158768
id(obj2.aa) =  4530158800

从上面我们可以看出bb和cc是公共字段,每个类都有唯一的副本,互不影响,需要使用类对象来访问,而Demo.aa和obj.aa是不同的,我们参见 obj.aa 的行为与普通字段类似。如果去掉obj1.aa=xx和obj2.aa=xx,那么obj1.aa和Demo.aa是一样的,它们在内存中的地址也是一样的。这涉及到python类的另一个特性——临时属性。

通常我们使用普通字段,当一个变量在类的所有对象中通用并且数据共享时,我们可以使用静态字段。

方法

方法包括:普通方法、静态方法、类方法。它们之间的区别在于它们的调用方式。

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

类方法:由类调用;包含一个 cls 参数;类方法执行时,调用该方法的类自动复制到cls;

静态方法:由类调用;没有默认参数;

class Foo:
    FooName = "静态字段"
    def custom_func(self, name):
        # 普通方法,至少包含一个self参数
        print("普通方法")    @classmethod
    def class_func(cls, name):
        # 类方法,至少包含一个cls参数
        print("类方法")    @staticmethod
    def static_func(name):
        # 静态方法,没有默认参数
        print("静态方法")

f = Foo()# 调用普通方法f.custom_func("aaa")# 调用类方法Foo.class_func("bbb")# 调用静态方法Foo.static_func("ccc")

普通方法中可以直接使用对象的普通字段self.name

类方法中可以直接使用静态字段cls.FooName

普通字段和静态字段不能直接在静态方法中使用

注意:静态字段Foo.FooName可以在任何地方调用,包括以上三种场景,如果还可以在通用方法中使用self.FooName,前提是对象没有同名的通用字段

属性

上面我们已经介绍了Python类中的方法,所以属性很简单,因为Python中的属性其实就是普通方法的变种。

对于属性,有以下两个知识点:

基本使用

两种定义方式

class Foo:
    def func(self):
        pass    @property
    def prop(self):
        print("属性")

f = Foo()# 调用函数f.func()# 调用属性f.prop

通过上面的例子,我们知道属性有以下几点:

普通方法上添加@property装饰器

有且只能有一个self参数,不能额外增加参数

调用时不需要括号

当我们显示网页数据时,数据的数据显示在页面上。不可能一次在页面上显示数据库中的所有内容。一般是通过分页功能实现的,所以每次请求都会根据当前页码current_page和每页显示的page_count个数来检索指定范围的数据

class Pager:
    def __init__(self, current_page):
        # 当前显示的页码
        self.current_page = current_page        # 每页默认显示数据
        self.per_items = 10    @property
    def start(self):
        return (self.current_page - 1) * self.per_items    @property
    def end(self):
        return self.current_page * self.per_items

pages = Pager(1)
pages.start # 起始值pages.end   # 结束值

属性的两种定义方式

属性的定义有两种方式:

装饰器:在方法上应用装饰器

静态字段:在类中定义值为property对象的静态字段

我们知道Python中的类分为经典类和新式类。如果一个类继承自object,那么这个类就是一个新式类,新式类的属性比经典类的属性更丰富。但是现在已经使用了python3,并且python3中的默认类都是从object继承的,所以python3中充满了新的类。

1. 装饰器方式:普通方法加上@property装饰器

class Goods:    @property
    def price(self):
        print("@property")    @price.setter
    def price(self, val):
        print("@price.setter: ", val)    @price.deleter
    def price(self):
        print("@price.deleter")

obj = Goods()
obj.price            # 自动执行@property修饰的price方法,并获取方法的返回值obj.price = 100  
                     #自动执行@price.setter修饰的price方法,并将100赋值给方法的参数del obj.price     
                     # 自动执行@price.deleter修饰的price方法

2. 静态字段方式,使用property创建静态字段

property是一个类,在builtins.py文件中,初始化函数:def __init__(self, fget=None, fset=None, fdel=None, doc=None),有四个参数

第一个参数fget是方法名,调用 对象.属性 时自动触发执行方法

第二个参数fset是方法名,调用object.property = XXX时会自动触发执行方法

第三个参数fdel是方法名,del对象时自动触发执行方法。属性被称为

第四个参数 doc 是一个字符串,调用 object.property.doc ,这个参数是属性的描述

class Foo:
    def __init__(self):
        self.price = 10

    def get_price(self):
        return self.price    # set函数必须有两个参数
    def set_price(self, value):
        self.price = value    def del_price(self):
        del self.price

    PRICE = property(get_price, set_price, del_price, "description Price")

f = Foo()
print(f.PRICE)    # 自动调用get_pricef.PRICE = 20     
                  # 自动调用set_priceprint(f.PRICE)    
                  # 自动调用del_pricedel f.PRICE        
                  # 自动调用description Price

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写
扫一扫二维码分享