Python property()函数:定义属性
我们一直在用“类对象.属性”的方式访问类中定义的属性,其实这种做法是欠妥的,因为它破坏了类的封装原则。
正常情况下,类包含的属性应该是隐藏的,只允许通过类提供的方法来间接实现对类属性的访问和操作。
因此,在不破坏类封装原则的基础上,为了能够有效操作类中的属性,类中应包含读(或写)类属性的多个 getter(或 setter)方法,这样就可以通过“类对象.方法(参数)”的方式操作属性,
例如:
这种操作类属性的方式比较麻烦,更习惯使用“类对象.属性”这种方式。
Python 中提供了 property() 函数,可以实现在不破坏类封装原则的前提下,让开发者依旧使用“类对象.属性”的方式操作类中的属性。
class CLanguage:
#构造函数
def __init__(self,n):
self.__name = n
#设置 name 属性值的函数
def setname(self,n):
self.__name = n
#访问nema属性值的函数
def getname(self):
return self.__name
#删除name属性值的函数
def delname(self):
self.__name="xxx"
#为name 属性配置 property() 函数
name = property(getname, setname, delname, '指明出处')
#调取说明文档的 2 种方式
#print(CLanguage.name.__doc__)
help(CLanguage.name)
clang = CLanguage("C语言中文网")
#调用 getname() 方法
print(clang.name)
#调用 setname() 方法
clang.name="Python教程"
print(clang.name)
#调用 delname() 方法
del clang.name
print(clang.name)
不要构造函数也可以,直接set和get方法处理:
当然,property() 函数也可以少传入几个参数。以上面的程序为例,我们可以修改 property() 函数如下所示
- name = property(getname, setname)
这意味着,name 是一个可读写的属性,但不能删除,因为 property() 函数中并没有为 name 配置用于函数该属性的方法。
也就是说,即便 CLanguage 类中设计有 delname() 函数,这种情况下也不能用来删除 name 属性。
同理,还可以像如下这样使用 property() 函数:
- name = property(getname) # name 属性可读,不可写,也不能删除
- name = property(getname, setname,delname) #name属性可读、可写、也可删除,就是没有说明文
===========================================================================
Python @property装饰器详解
首先讲解装饰器:一个函数可以作为另外一个函数的参数。装饰器接受一个函数,添加一些功能并返回它。
在复习之前,需要讲解如下几个知识点:
Python变量作用域(全局变量和局部变量)
Python局部变量:在函数内部定义的变量,它的作用域也仅限于函数内部,出了函数就不能使用了,我们将这样的变量称为局部变量(Local Variable)。
Python全局变量:除了在函数内部定义变量,Python 还允许在所有函数的外部定义变量,这样的变量称为全局变量(Global Variable)。
和局部变量不同,全局变量的默认作用域是整个程序,即全局变量既可以在各个函数的外部使用,也可以在各函数内部使用。
定义全局变量的方式有以下 2 种:
1、在函数体外定义的变量,一定是全局变量
2、在函数体内定义全局变量。即使用 global 关键字对变量进行修饰后,该变量就会变为全局变量
Python Global 关键字
全局关键字简介
在Python中,global关键字允许您在当前作用域之外修改变量。它用于创建全局变量并在局部上下文中对该变量进行更改。
全局关键字规则
Python中global关键字的基本规则是:
-
当我们在函数内部创建变量时,默认情况下它是局部的。
-
当我们在函数外部定义变量时,默认情况下它是全局的。您不必使用global关键字。
-
我们使用global关键字在函数内部读写全局变量。
-
在函数外使用global关键字无效
Python局部函数及用法(包含nonlocal关键字)
Python 支持在函数内部定义函数,此类函数又称为局部函数。
首先,和局部变量一样,默认情况下局部函数只能在其所在函数的作用域内使用。
重点:就如同全局函数返回其局部变量,就可以扩大该变量的作用域一样,通过将局部函数作为所在函数的返回值,也可以扩大局部函数的使用范围。
对于局部函数的作用域,可以总结为:
如果所在函数没有返回局部函数,则局部函数的可用范围仅限于所在函数内部;
反之,
如果所在函数将局部函数作为返回值,则局部函数的作用域就会扩大,既可以在所在函数内部使用,也可以在所在函数的作用域中使用。
以上面程序中的 outdef() 和 indef() 为例,如果 outdef() 不将 indef 作为返回值,则 indef() 只能在 outdef() 函数内部使用;
反之,
则 indef() 函数既可以在 outdef() 函数内部使用,也可以在 outdef() 函数的作用域,也就是全局范围内使用。
nonlocal
nonlocal关键字的使用与关键字global非常相似。
nonlocal用于声明嵌套函数内部的变量(函数内部的函数)不是局部变量,这意味着它位于外部封闭函数中。
如果需要在嵌套函数中修改非局部变量的值,则必须使用进行声明nonlocal。
否则,将在嵌套函数内创建具有该名称的局部变量。以下示例将帮助我们阐明这一点。
Python 闭包
嵌套函数中的非局部变量
在了解闭包是什么之前,我们必须首先了解什么是嵌套函数和非局部变量。
在另一个函数内部定义的函数称为嵌套函数。嵌套函数可以访问封闭范围的变量。
在Python中,默认情况下,这些非本地变量是只读的,并且我们必须将它们明确声明为非本地变量(使用nonlocal关键字)才能进行修改。
如下示例,我们可以看到嵌套函数printer()能够访问封闭函数的非局部变量msg。
闭包的条件?
从上面的实例可以看出,在Python中,当嵌套的函数在其封闭的范围内引用一个值时,我们有一个闭包。
以下几点总结了在Python中创建闭包必须满足的条件。
-
我们必须有一个嵌套函数(函数在函数内部)。
-
嵌套函数必须引用在封闭函数中定义的值。
-
封闭函数必须返回嵌套函数。
回到装饰器
函数和方法被称为可调用的,因为它们可以被调用。
实际上,任何实现特殊方法__call __()的对象都称为可调用的。 因此,从最基本的意义上讲,装饰器是可调用的,可返回可调用的。
基本上,装饰器接受一个函数,添加一些功能并返回它。