Python的面向对象

栏目: 后端 · 前端 · 发布时间: 7年前

内容简介:Python的面向对象

1. 进入 Python 的面向对象

python 作为一个弱类型的动态语言,其面向对象的方式与 Java 、C++这种强类型的语言相比还是有很大的不同的。其中Java、C++如何此处不作赘述。

首先,先预设这么一个类:

# code-01
class Person(object):
    def __init__(self, name):
        self.name = name
    def setName(self, name):
        self.name = name
    def getName(self):
        return self.name

像这样定义属性:

# code-02
    def __init__(self, name):
        self.name = name    # self.name 代表的就是定义的属性(先声明再定义?还是直接定义?由你决定!)

像这样定义函数:

# code-03
    def setName(self, name):        # 这里的setName()、getName()函数都可以通过实例来调用,self代表的是实例本身,
                                    # 其他函数的参数问题不在本文讨论之列,另外:注释不要像我这么写
        self.name = name
    def getName(self):
        return self.name

2. 访问控制

python 的访问控制干脆直接,属性 权限 从属性的 名字 上即可得到。

此处按照常规的访问权限解释:

  • public

code-01 的代码所示:

python # code-04 def __init__(self, name = '') self.name = name

这里的 self.name 就是 public 的,我们可以通过下面这种方式访问这个属性:

python # code-05 if __name__ == '__main__': p = Person("Marry") print(p.name) # 这里会输出: Marry

同样的,这里的 setName()getName() 也是 public 的,我们也可以通过下面这种方式来访问:

python # code-06 if __name__ == '__main__': p = Person("Marry") print(p.getName()) # 这里会输出: Marry

  • private

这里我们把上面 code-01 的代码修改 __init__(self,name) 函数,如下所示:

python # code-07 class Person(object): def __init__(self, name = "",marry = False): self.name = name self.__marry = marry

并添加如下代码,其他部分不变。

python # code-08 class Person(object): def __isMarry(self): return self.__marry

__isMarry(self) 这样的函数就是 private 函数, self.__marry 这样的属性(变量)就是 private 属性。

那么,如果再直接访问它的话,就会报错:

```python

# code-09

if name == ' main ':

p = Person("Marry")

print(p.getName()) # 这里会输出: Marry

print(p.__isMarry()) # 这里会报错

Traceback (most recent call last):

File "/media/somote/新加卷/pytest/ootest.py", line 16, in

  • protected

事实上,python 并不提供这个权限,所以在此不作描述。

3. 内置装饰器

@property

先说一下property()函数,这里有必要提一下类的三个内置函数:setattr、getattr(以及getattribute)、delattr,关于关于这三个函数该如何使用,请自行搜索

property()的作用就在于把 setattrgetattrdelattr 三个函数给统一起来,如下所示:

# code-10
class Girl (Person):
    """
    我们新增一个 Girl 类,继承自 Person,同时我们为它新增一些身材属性 bust、waist、hip
    """

    def __init__(self, name):
        super(Girl, self).__init__(name)
        self.bust = 80
        self.waist = 80
        self.hip = 80
    # 这里的 figure 参数实际上就是*args(tuple类型)
    def setfigure(self, figure):
        self.bust, self.waist, self.hip = figure

    def getfigure(self):
        return self.bust, self.waist, self.hip

    def delfigure(self):
        del self.bust
        del self.waist
        del self.hip
    # 这里是重点
    figure = property(getfigure, setfigure, delfigure)

运行:

# code-11
if __name__ == '__main__':
    g = Girl("Jane")
    print(g.name)
    g.setfigure((50,60,90))     # 通过函数来设置
    print(g.getfigure())# 50,60,90
    '''
    通过figure属性,绑定到其property()函数的 setter、getter、deller函数上,注意:这里必须把参数给齐,否则会报错
    '''
    g.figure = 60,90,90         
    print(g.figure)     # 60,90,90
    print(g.bust)   # 60
    print(g.waist)  # 90
    print(g.hip)    # 90

我们也可以通过 @property 来设置属性:

# code-12
class Girl (Person):
    """
    我们新增一个 Girl 类,继承自 Person,同时我们为它新增一些身材属性 bust、waist、hip
    """
    def __init__(self, name):
        super(Girl, self).__init__(name)
        self.bust = 80
        self.waist = 80
        self.hip = 80

    # 这里预先把 figure() 装饰為 figure属性,所以可以在下面设置 setter、deleter,注意: getter 由这里的figure()代替了
    @property
    def figure(self):
        print("get value")
        return self.bust, self.waist, self.hip
    
    @figure.setter
    def figure(self, figure):
        print("set value")
        self.bust, self.waist, self.hip = figure

    @figure.deleter
    def figure(self):
        del self.bust
        del self.waist
        del self.hip

运行:

# code-13
if __name__ == '__main__':
    g = Girl("Jane")
    print(g.name)           # Jane
    g.figure = 60,90,90     # set value
    print(g.figure)         # get value
                            # 60,90,90
    print(g.bust)   # 60
    print(g.waist)  # 90
    print(g.hip)    # 90

通过 property()@property 这种方式,可以控制某些属性的读写权限

@staticmethod

顾名思义, staticmethod 就是静态方法的意思,那么首先先来了解一下静态属性,在 code-12 的代码里,我们作如下修改:

# code-14
class Girl (Person):
    girlsnum = 0
    # primary code here

运行:

# code-15
if __name__ == '__main__':
    g = Girl("Jane")
    print(g.girlsnum)       # 1
    g1 = Girl("Marry")
    print(g.girlsnum)       # 2
    g2 = Girl("Lucy")
    print(g1.girlsnum)      # 3
    print(Girl.girlsnum)    # 3

可以看出, girlsnum 这个属性就是一个静态的类属性,那么 staticmethod 呢?

我们在 code-12 的基础上再次添加一些内容:

# code-16
class Girl (Person):
    # primary code here
    @staticmethod
    def info(name="", figure=()):
        return "Name : " + name + " \tFigure : " + str(figure)

然后运行:

# code-17
if __name__ == '__main__':
    g = Girl("Jane")
    print(Girl.info("Jane", g.figure))      # Name : Jane     Figure : (80, 80, 80)

或许,你灵机一动把 info(name="", figure=()) 改为 info(self,name="", figure=()) ,那么去看看会发生什么吧![^1]

@classmethod

其实 @classmethod@staticmethod 很难说到底有什么不同,水平有限,其具体用途留待探讨,此处只作简要说明。我们在 code-12 的基础上作如下修改:

# code-18
class Girl (Person):
    # primary code here
    @classmethod
    def build(clazz):
        print("ClassMethod")

运行:

# code-19
if __name__ == '__main__':
    g = Girl("Jane")
    Girl.build()        # ClassMethod

注意:

  1. @classmethod 所装饰的函数,最少需要一个参数,并且这个参数就是当前类本身
  2. 就调用而言, instancemethod_要宽泛于_staticmethod_和_classmethod (实例可以调用静态方法或者类方法,反之不可)

4. 某些属性

__dict__

__dict__ 主要保存的是实例的属性键值对,我们对 code-12 的代码作如下修改并运行:

# code-20
if __name__ == '__main__':
    g = Girl("Jane")
    print(g.__dict__)   # {'hip': 80, 'name': 'Jane', 'bust': 80, 'waist': 80}

注意: @property 所装饰的 figure 并没有作为属性被打印出来

__slots__

我们对 code-12 的代码作如下修改:

# code-07
class Girl (Person):
    __slots__ = ("bust", "waist", "hip")
    # primary code here

此时,Girl类应当只有三个属性: bustwaisthip 了,但是事实并非如此,我们运行如下代码:

# code-21
if __name__ == '__main__':
    g = Girl("Jane")
    g.age = 25

发现仍能通过,并且通过 dir(g) 可以查看到age属性,为什么呢?

原因在于: Girl 的基类 Person 并没有用 __slots__ 来限制属性,也就是说 __slots__ 的作用范围仅仅包括当前类,所以:

# code-22
class Person(object):
    __slots__ = ("name")
    # primary code here

此时,再次运行 code-21 就会发现解释器会报错


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Access2003数据库开发典型范例

Access2003数据库开发典型范例

王樵民 / 第1版 (2006年8月1日) / 2006-8 / 42.00元

Access数据库管理软件是一套集数据管理、程序开发功能于一体的高级办公软件,是特别适合普通办公人员进行日常工作的有力助手。本书面向非计算机专业人员,通过多个实例讲解Access中的各种开发技术,介绍实际工作过程中应用软件的编制方法,以及与Excel等软件之间的信息互用技术等内容。能够帮助读者快速掌握Access数据库的开发技术,构建解决自己工作中实际问题的数据库管理系统,从而提高办公效率。一起来看看 《Access2003数据库开发典型范例》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

MD5 加密
MD5 加密

MD5 加密工具