2019独角兽企业重金招聘Python工程师标准>>>

类中的特殊方法

一般说来,特殊的方法都被用来模仿某个行为。例如,如果你想要为你的类使用x[key]这样的索引操作(就像列表和元组一样),那么你只需要实现__getitem__()方法就可以了。想一下,Python就是对list类这样做的!

下面这个表中列出了一些有用的特殊方法。如果你想要知道所有的特殊方法,你可以在《Python参考手册》中找到一个庞大的列表。

名称                     说明
---------------------------------------------------------
__init__ (self,...)      这个方法在新建对象恰好要被返回使用之前被调用。
__del__ (self)           恰好在对象要被删除之前调用。
__str__ (self)           在我们对对象使用print语句或是使用str()的时候调用。
__lt__ (self,other)      当使用 小于 运算符( < )的时候调用。类似地,对于所有的运算符( + , > 等等)都有特殊的方法。
__getitem__ (self,key)   使用x[key]索引操作符的时候调用。
__len__ (self)           对序列对象使用内建的len()函数的时候调用。
__repr__ (s)             repr()  and  `...` conversions
__cmp__ (s, o)           Compares s to o  and  returns  < 0, 0,  or   > 0. 
                        Implements  > ,  < ,  ==  etc...
__hash__ (s)             Compute a  32  bit hash code; hash()  and  dictionary ops
__nonzero__ (s)          Returns 0  or   1   for  truth value testing
__getattr__ (s, name)    called when attr lookup doesn ' t find <name>
__setattr__ (s, name, val) called when setting an attr
                        (inside, don ' t use "self.name = value"
                        use  " self.__dict__[name] = val " )
__delattr__ (s, name)    called to delete attr  < name >
__call__ (self,  * args)   called when an instance  is  called as function.

exec和eval语句

exec语句用来执行储存在字符串或文件中的Python语句。例如,我们可以在运行时生成一个包含Python代码的字符串,然后使用exec语句执行这些语句。
下面是一个简单的例子。

>>>   exec   ' print "Hello World" '
Hello World

eval语句用来计算存储在字符串中的有效Python表达式。下面是一个简单的例子。

>>>  eval( ' 2*3 ' )
6  

repr函数用来取得对象的规范字符串表示。反引号(也称转换符)可以完成相同的功能。注意,在大多数时候有eval(repr(object)) == object。

>>>  i  =  []
>>>  i.append( ' item ' )
>>>  `i`
" ['item'] "
>>>  repr(i)
" ['item'] "

基本上,repr函数和反引号用来获取对象的可打印的表示形式。你可以通过定义类的__repr__方法来控制你的对象在被repr函数调用的时候返回的内容。

类和实例变量

有两种类型的域 —— 类的变量和对象的变量,它们根据是类还是对象拥有这个变量而区分。

类的变量 由一个类的所有对象(实例)共享使用。只有一个类变量的拷贝,所以当某个对象对类的变量做了改动的时候,这个改动会反映到所有其他的实例上。

对象的变量 由类的每个对象/实例拥有。因此每个对象有自己对这个域的一份拷贝,即它们不是共享的,在同一个类的不同实例中,虽然对象的变量有相同的名称,但是是互不相关的。通过一个例子会使这个易于理解。

#!/usr/bin/python
# Filename: inherit.pyclass SchoolMember:'''Represents any school member.'''def __init__(self, name, age):self.name = nameself.age = ageprint '(Initialized SchoolMember: %s)' % self.namedef tell(self):'''Tell my details.'''print 'Name:"%s" Age:"%s"' % (self.name, self.age),class Teacher(SchoolMember):'''Represents a teacher.'''def __init__(self, name, age, salary):SchoolMember.__init__(self, name, age)self.salary = salaryprint '(Initialized Teacher: %s)' % self.namedef tell(self):SchoolMember.tell(self)print 'Salary: "%d"' % self.salaryclass Student(SchoolMember):'''Represents a student.'''def __init__(self, name, age, marks):SchoolMember.__init__(self, name, age)self.marks = marksprint '(Initialized Student: %s)' % self.namedef tell(self):SchoolMember.tell(self)print 'Marks: "%d"' % self.markst = Teacher('Mrs. Shrividya', 40, 30000)
s = Student('Swaroop', 22, 75)print # prints a blank linemembers = [t, s]
for member in members:member.tell() # works for both Teachers and Students输出$ python inherit.py
(Initialized SchoolMember: Mrs. Shrividya)
(Initialized Teacher: Mrs. Shrividya)
(Initialized SchoolMember: Swaroop)
(Initialized Student: Swaroop)Name:"Mrs. Shrividya" Age:"40" Salary: "30000"
Name:"Swaroop" Age:"22" Marks: "75"

这是一个很长的例子,但是它有助于说明类与对象的变量的本质。这里,population属于Person类,因此是一个类的变量。name变量属于对象(它使用self赋值)因此是对象的变量。

观察可以发现__init__方法用一个名字来初始化Person实例。在这个方法中,我们让population增加1,这是因为我们增加了一个人。同样可以发现,self.name的值根据每个对象指定,这表明了它作为对象的变量的本质。

记住,你只能使用self变量来参考同一个对象的变量和方法。这被称为 属性参考 。

在这个程序中,我们还看到docstring对于类和方法同样有用。我们可以在运行时使用Person.__doc__和Person.sayHi.__doc__来分别访问类与方法的文档字符串。

就如同__init__方法一样,还有一个特殊的方法__del__,它在对象消逝的时候被调用。对象消逝即对象不再被使用,它所占用的内存将返回给系统作它用。在这个方法里面,我们只是简单地把Person.population减1。

当对象不再被使用时,__del__方法运行,但是很难保证这个方法究竟在什么时候运行。如果你想要指明它的运行,你就得使用del语句,就如同我们在以前的例子中使用的那样。

给C++/Java/C#程序员的注释
Python中所有的类成员(包括数据成员)都是公共的 ,所有的方法都是有效的。
只有一个例外:如果你使用的数据成员名称以双下划线前缀 比如__privatevar,Python的名称管理体系会有效地把它作为私有变量。
这样就有一个惯例,如果某个变量只想在类或对象中使用,就应该以单下划线前缀。而其他的名称都将作为公共的,可以被其他类/对象使用。记住这只是一个惯例,并不是Python所要求的(与双下划线前缀不同)。
同样,注意__del__方法与destructor的概念类似。

* 转义符

假设你想要在一个字符串中包含一个单引号('),那么你该怎么指示这个字符串?例如,这个字符串是What's your name?。你肯定不会用'What's your name?'来指示它,因为Python会弄不明白这个字符串从何处开始,何处结束。所以,你需要指明单引号而不是字符串的结尾。可以通过 转义符 来完成这个任务。你用/'来指示单引号——注意这个反斜杠。现在你可以把字符串表示为'What/'s your name?'。

私有变量

Python对私有类成员有部分支持。任何象__spam这样形式的标识符(至少有两个前导下划线,至多有一个结尾下划线)目前被替换成_classname__spam,其中classname是所属类名去掉前导下划线的结果。这种搅乱不管标识符的语法位置,所以可以用来定义类私有的实例、变量、方法,以及全局变量,甚至于保存对于此类是私有的其它类的实例。如果搅乱的名字超过255个字符可能会发生截断。在类外面或类名只有下划线时不进行搅乱。

名字搅乱的目的是给类一种定义“私有”实例变量和方法的简单方法,不需担心它的其它类会定义同名变量,也不怕类外的代码弄乱实例的变量。注意搅乱规则主要是为了避免偶然的错误,如果你一定想做的话仍然可以访问或修改私有变量。这甚至是有用的,比如调试程序要用到私有变量,这也是为什么这个漏洞没有堵上的一个原因。(小错误:导出类和基类取相同的名字就可以使用基类的私有变量)。

注意传递给exec,eval()或evalfile()的代码不会认为调用它们的类的类名是当前类,这与global语句的情况类似,global的作用局限于一起字节编译的代码。同样的限制也适用于getattr() ,setattr()和delattr(),以及直接访问__dict__的时候。

下面例子中的类实现了自己的__getattr__和__setattr__方法,把所有属性保存在一个私有变量中,这在Python的新旧版本中都是可行的:

class VirtualAttributes: __vdict = None__vdict_name = locals().keys()[0]    def __init__(self):self.__dict__[self.__vdict_name] = {}def __getattr__(self, name):return self.__vdict[name]def __setattr__(self, name, value): self.__vdict[name] = value

refer to:http://blog.csdn.net/nilxin/article/details/1613574

转载于:https://my.oschina.net/dacoolbaby/blog/352928

Python(私有变量)类中的特殊方法相关推荐

  1. python私有变量_python中的私有变量

    classTest1:deff1(self): self.name="张三"self.__age = 20 #使用名称变形实现私有变量 print(self.name)print( ...

  2. python中的object是什么意思_Python object类中的特殊方法代码讲解

    python版本:3.8class object: """ The most base type """ # del obj.xxx或del ...

  3. 《Python面向对象编程指南》——1.2 基类中的__init__()方法

    本节书摘来自异步社区<Python面向对象编程指南>一书中的第1章,第1.2节,作者[美]Steven F. Lott, 张心韬 兰亮 译,更多章节内容可以访问云栖社区"异步社区 ...

  4. python类中的魔方方法

    在python中有些方法名比较特别,在名称的前后各有两个下划线,这样的方法往往具有特殊的意义,一般情况下我们不会直接用到所以称之为"隐藏方法"也有一些人称之为"魔法方法& ...

  5. python 多继承 __new___Python3中的__new__方法以及继承不可变类型类的问题

    最近在学到Python中的__new__方法时被弄懵逼了,一开始实在是很难理解,有很多地方想不通(本人强迫症).最近自己慢慢思索得出了能说服自己的理解: 说__new__方法之前要先提到__init_ ...

  6. python中property魔法方法原理_Python类中的魔法方法之 __slots__原理解析

    在类中每次实例化一个对象都会生产一个字典来保存一个对象的所有的实例属性,这样非常的有用处,可以使我们任意的去设置新的属性. 每次实例化一个对象python都会分配一个固定大小内存的字典来保存属性,如果 ...

  7. python写一个类方法_重写python脚本,在脚本的每个类中注入一个方法 - python

    假设我有一个python模块foo.py,其中包含: class Foo(object): def __init__(self): pass 接下来,我想解析此脚本,并在每个类中注入一个方法,然后将其 ...

  8. python extract方法_在多个项目类中使用extract方法

    我不是一个有经验的程序员,不要生我的气- 我正在探索一些小的可能性(我有一些Python编程技巧).在 废弃一个网站:让我们想象一下,我们可以从opengraph(og:)中提取一些信息,比如&quo ...

  9. Python 类中的__call__()方法

    Python call()方法 在类中实现__call__()方法,可以在实例化一个该类的对象后,直接调用该对象,像使用函数一样,这样实现的就是__call__()方法中的内容. 举例: 太长不看版 ...

最新文章

  1. 新手零基础学习Python第一步,搭建开发环境!
  2. 动物统计加强版(贪心,字典序)
  3. Hi3516A开发--apt-get更新
  4. 【期望】关灯游戏(金牌导航 期望-8)
  5. oracle9i 全库备份,Windows下Oracle9i数据库文件如何自动备份?
  6. mysql大表数据抽取_从云数据迁移服务看MySQL大表抽取模式
  7. react echarts 绘制带有滑块柱图
  8. C# 获取当前路径或父路径
  9. Fliqlo时钟屏保无毒Windows/Mac版
  10. CCF201809-4 再卖菜(100分)
  11. maven找不到,变小蜘蛛问题
  12. mac 百度输入法如何切换成五笔,如何切换回拼音模式
  13. 【编程生活】自动化数据均分助手
  14. 从头搭建一个“微博”有多难
  15. 计算机设置任务栏的大小要先,教你win7系统电脑调整任务栏预览窗口大小的方法...
  16. 解决idea中每次创建项目都要重复配置maven,全网几步配置
  17. N1刷openwrt,部分app图片无法显示
  18. 【四】Java设计模式GOF23之抽象工厂模式
  19. pthread_cancel pthread_testcancel测试
  20. 这就是神经网络 1:早期分类网络之LeNet-5、AlexNet、ZFNet、OverFeat、VGG

热门文章

  1. Calibre 制作电子书
  2. 用计算机获取机读卡是通过什么实现的,一种基于图像识别技术的答题卡及考试系统的制作方法...
  3. unity Quad剔除背面并剔除透明部分的shader
  4. bosun_与Bosun一起监控
  5. STM32+0.96OLED的多级菜单设计
  6. Appium 不懂就问,Appium 小白,在微信切换 webview 时遇到 Original error: unknown error: Failed to get PID for
  7. python zip()和zip(*)方法
  8. 学python还是c加加更实用_c语言和python先学哪个比较简单
  9. html语义化标签 例子,0820作业:HTML5新增语义化标签及实战总结
  10. Hadoop能做什么