python 函数是不是描述符在Python中,访问一个属性的优先级顺序按照如下顺序:
1.类属性
2.数据描述符
3.实例属性
4.非数据描述符
5.__getattr__()方法 。这个方法的完整定义如下所示:
[python] view plain copy
def __getattr__(self,attr) :#attr是self的一个属性名
pass;
先来阐述下什么叫数据描述符 。
数据描述符是指实现了__get__,__set__,__del__方法的类属性(由于Python中,一切皆是对象,所以你不妨把所有的属性也看成是对象)
PS:个人觉得这里最好把数据描述符等效于定义了__get__,__set__,__del__三个方法的接口 。
阐述下这三个方法:
__get__的标准定义是__get__(self,obj,type=None),它非常接近于JavaBean的get
第一个函数是调用它的实例,obj是指去访问属性所在的方法,最后一个type是一个可选参数,通常为None(这个有待于进一步的研究)
例如给定类X和实例x,调用x.foo,等效于调用:
type(x).__dict__["foo"].__get__(x,type(x))
调用X.foo,等效于调用:
type(x).__dict__["foo"].__get__(None,type(x))
第二个函数__set__的标准定义是__set__(self,obj,val) , 它非常接近于JavaBean的set方法,其中最后一个参数是要赋予的值
第三个函数__del__的标准定义是__del__(self,obj),它非常接近Java中Object的Finailize()方法,指
Python在回收这个垃圾对象时所调用到的析构函数,只是这个函数永远不会抛出异常 。因为这个对象已经没有引用指向它,抛出异常没有任何意义 。
接下来 , 我们来一一比较这些优先级.
首先来看类属性
[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class A(object):
foo=3
print A.foo
a=A()
print a.foo
a.foo=4
print a.foo
print A.foo
上面这段代码的输出如下:
3
3
4
3
从输出可以看到,当我们给a.foo赋值的时候,其实与类实例的那个foo是没有关系的 。a.foo=4 这句话给a对象增加了一个属性叫foo 。其值是4 。
最后两个语句明确的表明了,我们输出a.foo和A.foo的值,他们是不同的 。
【python数据描述函数 python 描述性统计】但是为什么a=A()语句后面的print
a.foo输出了3呢?这是因为根据搜索顺序找到了类属性 。当我们执行a.foo=4的时候,我们让a对象的foo属性指向了4这个对象 。但是并没有改变
类属性foo的值 。所以最后我们print A.foo的时候,又输出了3 。
[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class A(object):
foo=3
a=A()
a.foo=4
print a.foo
del a.foo
print a.foo
上面的代码 , 我给a.foo赋值为4,在输出一次之后就del了 。两次输出,第一次输出的是a对象的属性 。第二次是类属性 。不是说类属性的优先级比
实例属性的高吗 。为啥第一次输出的是4而不是3呢?还是上面解释的原因 。因为a.foo与类属性的foo只是重名而已 。我们print
a.foo的时候,a的foo指向的是4,所以输出了4 。
------------------------------------
然后我们来看下数据描述符这一全新的语言概念 。按照之前的定义,一个实现了__get__,__set__,__del__的类都统称为数据描述符 。我们来看下一个简单的例子 。
[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class simpleDescriptor(object):
def __get__(self,obj,type=None):
pass
def __set__(self,obj,val):
pass
def __del__(self,obj):
pass
class A(object):
foo=simpleDescriptor()
print str(A.__dict__)
print A.foo
a=A()
print a.foo
a.foo=13
print a.foo
上面例子的输出结果如下:
[plain] view plain copy
{'__dict__': attribute '__dict__' of 'A' objects, '__module__': '__main__', 'foo': __main__.simpleDescriptor object at 0x005511B0, '__weakref__': attribute '__weakref__' of 'A' objects, '__doc__': None}
None
None
None
从输出结果看出 , print语句打印出来的都是None 。这说明a.foo都没有被赋值内容 。这是因为__get__函数的函数体什么工作都没有做 。直接是pass 。此时,想要访问foo,每次都没有返回内容 , 所以输出的内容就是None了 。
[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class simpleDescriptor(object):
def __get__(self,obj,type=None):
return "hi there"
def __set__(self,obj,val):
pass
def __del__(self,obj):
pass
class A(object):
foo=simpleDescriptor()
print str(A.__dict__)
print A.foo
a=A()
print a.foo
a.foo=13
print a.foo
把__get__函数实现以下,就可以得到如下输出结果:
[plain] view plain copy
{'__dict__': attribute '__dict__' of 'A' objects, '__module__': '__main__', 'foo': __main__.simpleDescriptor object at 0x00671190, '__weakref__': attribute '__weakref__' of 'A' objects, '__doc__': None}
hi there
hi there
hi there
为了加深对数据描述符的理解,看如下例子:
[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class simpleDescriptor(object):
def __init__(self):
self.result = None;
def __get__(self, obj, type=None) :
return self.result - 10;
def __set__(self, obj, val):
self.result = val3;
print self.result;
def __del__(self, obj):
pass
class A(object):
foo = simpleDescriptor();
a = A();
a.foo = 13;
print a.foo;
上面代码的输出是
16
6
第一个16为我们在对a.foo赋值的时候,人为的将13加上3后作为foo的值,第二个6是我们在返回a.foo之前人为的将它减去了10 。
所以我们可以猜测,常规的Python类在定义get,set方法的时候 , 如果无特殊需求 , 直接给对应的属性赋值或直接返回该属性值 。如果自己定义类,并且继承object类的话,这几个方法都不用定义 。
-----------------
在这里看一个题外话 。
看代码
[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class simpleDescriptor(object):
def __init__(self):
self.result = None;
def __get__(self, obj, type=None) :
return self.result - 10;
def __set__(self, obj, val):
if isinstance(val,str):
assert False,"int needed! but get str"
self.result = val3;
print self.result;
def __del__(self, obj):
pass
class A(object):
foo = simpleDescriptor();
a = A();
a.foo = "13";
print a.foo;
上面代码在__set__ 函数中检查了参数val , 如果val是str类型的 , 那么要报错 。这就实现了我们上一篇文章中要实现的 , 在给属性赋值的时候做类型检查的功能 。
-----------------------------------------------
下面我们来看下实例属性和非数据描述符 。
[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class B(object):
foo = 1.3
b = B()
print b.__dict__
b.bar = 13
print b.__dict__
print b.bar
上面代码输出结果如下:
{}
{'bar': 13}
13
那么什么是非数据描述符呢?
简单的说,就是没有实现get,set,del三个方法的所有类 。
让我们任意看一个函数的描述:
def call():
pass
执行print dir(call)会得到如下结果:
[plain] view plain copy
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
先看下dir的帮助 。
dir列出给定对象的属性或者是从这个对象能够达到的对象 。
回到print dir(call)方法的输出 , 看到,call方法,有输出的那么多个属性 。其中就包含了__get__函数 。但是却没有__set__和__del__函数 。所以所有的类成员函数都是非数据描述符 。
看一个实例数据掩盖非数据描述符的例子:
[python] view plain copy
'''''
Created on 2013-3-29
@author: naughty
'''
class simpleDescriptor(object):
def __get__(self,obj,type=None) :
return "get",self,obj,type
class D(object):
foo=simpleDescriptor()
d=D()
print d.foo
d.foo=15
print d.foo
看输出:
('get', __main__.simpleDescriptor object at 0x02141190,
__main__.D object at 0x025CAF50, class '__main__.D')
15
可见,实例数据掩盖了非数据描述符 。
如果改成数据描述符 , 那么就不会被覆盖了 。看下面:
[python] view plain copy
'''''
Created on 2013-3-29
@author: naughty
'''
class simpleDescriptor(object):
def __get__(self,obj,type=None) :
return "get",self,obj,type
def __set__(self,obj,type=None) :
pass
def __del__(self,obj,type=None) :
pass
class D(object):
foo=simpleDescriptor()
d=D()
print d.foo
d.foo=15
print d.foo
代码的输出如下:
[plain] view plain copy
('get', __main__.simpleDescriptor object at 0x01DD1190, __main__.D object at 0x0257AF50, class '__main__.D')
('get', __main__.simpleDescriptor object at 0x01DD1190, __main__.D object at 0x0257AF50, class '__main__.D')
由于是数据描述符,__set __函数体是pass,所以两次输出都是同样的内容 。
最后看下__getatrr__方法 。它的标准定义是:__getattr__(self,attr),其中attr是属性名
Python中的常用内置函数有哪些呢?(1)Lambda函数
用于创建匿名函数python数据描述函数,即没有名称的函数 。它只是一个表达式,函数体比def简单很多 。当python数据描述函数我们需要创建一个函数来执行单个操作并且可以在一行中编写时,就可以用到匿名函数python数据描述函数了 。
Lamdba的主体是一个表达式,而不是一个代码块 。仅仅能在lambda表达式中封装有限的逻辑进去 。
利用Lamdba函数 , 往往可以将代码简化许多 。
(2)Map函数
会将一个函数映射到一个输入列表的所有元素上,比如我们先创建python数据描述函数了一个函数来返回一个大写的输入单词,然后将此函数应有到列表colors中的所有元素 。
我们还可以使用匿名函数lamdba来配合map函数 , 这样可以更加精简 。
(3)Reduce函数
当需要对一个列表进行一些计算并返回结果时,reduce()是个非常有用的函数 。举个例子,当需要计算一个整数列表所有元素的乘积时,即可使用reduce函数实现 。
它与函数的最大的区别就是,reduce()里的映射函数(function)接收两个参数 , 而map接收一个参数 。
(4)enumerate函数
用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在for循环当中 。
它的两个参数 , 一个是序列、迭代器或其python数据描述函数他支持迭代对象;另一个是下标起始位置,默认情况从0开始,也可以自定义计数器的起始编号 。
(5)Zip函数
用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表
当我们使用zip()函数时 , 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同 。
python中函数定义1、函数定义
①使用def关键字定义函数
②
def 函数名(参数1.参数2.参数3...):
"""文档字符串,docstring,用来说明函数的作用"""
#函数体
return 表达式
注释的作用:说明函数是做什么的,函数有什么功能 。
③遇到冒号要缩进,冒号后面所有的缩进的代码块构成了函数体,描述了函数是做什么的,即函数的功能是什么 。Python函数的本质与数学中的函数的本质是一致的 。
2、函数调用
①函数必须先定义,才能调用,否则会报错 。
②无参数时函数的调用:函数名() , 有参数时函数的调用:函数名(参数1.参数2.……)
③不要在定义函数的时候在函数体里面调用本身,否则会出不来,陷入循环调用 。
④函数需要调用函数体才会被执行,单纯的只是定义函数是不会被执行的 。
⑤Debug工具中Step into进入到调用的函数里,Step Into My Code进入到调用的模块里函数 。
python中函数包括1. print()函数python数据描述函数:打印字符串
2. raw_input()函数:从用户键盘捕获字符
3. len()函数:计算字符长度
4. format(12.3654python数据描述函数,'6.2f'/'0.3%')函数:实现格式化输出
5. type()函数:查询对象python数据描述函数的类型
6. int()函数、float()函数、str()函数等:类型python数据描述函数的转化函数
7. id()函数:获取对象python数据描述函数的内存地址
8. help()函数:Python的帮助函数
9. s.islower()函数:判断字符小写
10. s.sppace()函数:判断是否为空格
11. str.replace()函数:替换字符
12. import()函数:引进库
13. math.sin()函数:sin()函数
14. math.pow()函数:计算次方函数
15. 3**4: 3的4次方
16. pow(3,4)函数:3的4次方
17. os.getcwd()函数:获取当前工作目录
18. listdir()函数:显示当前目录下的文件
19. socket.gethostbyname()函数:获得某主机的IP地址
20. urllib.urlopen(url).read():打开网络内容并存储
21. open().write()函数:写入文件
22. webbrowser.open_new_tab()函数:新建标签并使用浏览器打开指定的网页
23. def function_name(parameters):自定义函数
24. time.sleep()函数:停止一段时间
25. random.randint()函数:产生随机数
关于python数据描述函数和python 描述性统计的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息 , 记得收藏关注本站 。
推荐阅读
- go语言中判断月份,go类型判断
- 在html中怎样编写C语言代码,html怎么调用c语言
- 库尔勒代理记账财务软件,库尔勒财务公司大全
- 博学谷go语言视频 博学谷系统功能介绍
- 车载显示器接电视怎么接,车载显示器如何放电视
- PDF怎么导进去,pdf怎么导入到word
- 微信直播火爆,微信直播火不火
- linux保存命令的内容 linux命令保存文件
- 专题摄影的拍摄内容是什么,摄影定理的内容是什么