`
dacoolbaby
  • 浏览: 1265902 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

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.py

class SchoolMember:
    '''Represents any school member.'''
    def __init__(self, name, age):
        self.name = name
        self.age = age
        print '(Initialized SchoolMember: %s)' % self.name

    def 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 = salary
        print '(Initialized Teacher: %s)' % self.name

    def tell(self):
        SchoolMember.tell(self)
        print 'Salary: "%d"' % self.salary

class Student(SchoolMember):
    '''Represents a student.'''
    def __init__(self, name, age, marks):
        SchoolMember.__init__(self, name, age)
        self.marks = marks
        print '(Initialized Student: %s)' % self.name

    def tell(self):
        SchoolMember.tell(self)
        print 'Marks: "%d"' % self.marks

t = Teacher('Mrs. Shrividya', 40, 30000)
s = Student('Swaroop', 22, 75)

print # prints a blank line

members = [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

分享到:
评论

相关推荐

    python 类的私有变量和私有方法.docx

    在Python编程语言中,类的成员变量和方法的可见性和访问控制与其他面向对象的语言有所不同。Python没有显式的`public`、`private`或`protected`关键字来标识成员的访问级别,但通过一定的命名约定,我们可以实现类似...

    Python私有变量的用法共1页.pdf.zip

    Python私有变量是编程中的一个重要概念,特别是在面向对象编程中。私有变量,也称为受保护的变量,是为了实现封装而设计的,它的主要目的是限制类的内部成员(变量和方法)对外部代码的直接访问,以保持数据的安全性...

    浅谈Python中的私有变量

    私有变量表示方法 在变量前加上两个下划线的是私有变量。 class Teacher(): def __init__(self,name,level): self.__name=name self.__level=level #获取老师的等级 def get_level(self): return self.__...

    Python面向对象程序设计之私有变量,私有方法原理与用法分析

    在python中定义私有变量和私有方法只需要在变量名或函数名前加上 “__”两个下划线 在类内部的方法中使用时 self.__变量名或函数名。 实际上,如果真要访问私有变量和私有方法,也是可以访问的,因为实际上私有...

    第七章Python对象和类习题及答案--中文

    例如,在类 A 中,我们可以定义一个 `getY` 方法来访问私有变量 `__y`。 对象的引用 在 Python 中,对象的引用是指对象的内存地址。例如,使用类 Person,我们可以创建一个对象 John,并将其引用赋值给变量 `x`。 ...

    Python类如何定义私有变量

    ### Python 类中的私有变量与方法详解 #### 引言 在面向对象编程语言中,封装是一种保护数据安全的重要机制。Python作为一种高级编程语言,在处理类的私有成员时采用了不同的方式来实现这一功能。虽然Python不像...

    Python面向对象程序设计中类的定义、实例化、封装及私有变量/方法详解

    ### Python面向对象程序设计中类的定义、实例化、封装及私有变量/方法详解 #### 1. 定义类 在Python中,面向对象编程(Object-Oriented Programming, OOP)是一种重要的编程范式,它使得代码更加模块化、可重用,...

    Python语言基础:类的变量方法.pptx

    在这个文档中,我们将深入探讨Python类的变量和方法,以及如何使用`self`关键字。 首先,`self`是一个指向类实例的引用,它在类的方法中被用来访问类的属性和方法。在`描述`中给出的实例中,我们看到`self`被用来...

    08-python--writing-classes-特殊方法-属性

    在Python编程中,类是创建对象的蓝图,...通过实践和学习`08.05-python-特殊方法.ipynb`、`08.06-python-属性.ipynb`以及`08.04-python-writing-classes.ipynb`中的示例,你可以进一步巩固这些概念并应用到实际项目中。

    Python 类的私有属性和私有方法实例分析

    __xx:私有变量或方法(伪私有),类外部不能直接访问。 __xx__:公有变量或方法,子类可以访问。魔法方法或属性(例如:__init__),不推荐这样命名。 xx_:公有变量或方法。一般为了避免和python关键字冲突,不推荐这样命名...

    Python 类的说明

    根据提供的文件信息,我们可以从中提炼出关于Python类的多个关键...通过以上分析可以看出,Python中的类提供了丰富的功能,包括类变量、实例变量、不同类型的类方法以及继承等机制,这些都是构建复杂程序结构的基础。

    python私有属性和方法实例分析

    在python中定义私有变量只需要在变量名或函数名前加上 “__”两个下划线,那么这个函数或变量就会为私有的了。 在内部,python使用一种 name mangling 技术,将 __membername替换成 _classname__membername,所以你...

    private-var-implementation:python中私有变量的实现

    这是一个在python类中展示私有变量的演示。您可能知道,python在类中绝对没有私有变量。您可以实现的最接近的方法是,在诸如__foo之类的变量之前使用__运算符。这样,python会自动将变量重命名为_ &lt;\ class-name&gt;...

    Python七大类常见问题详解.rar

    Python迭代器生成器,私有变量及推导式(二) Python装饰器AOP 不定长参数 鸭子类型 重载(三) Python新式类 new init 单例模式与作用域(四) Python 进程线程协程 GIL 闭包 与高阶函数(五) Python中深浅拷贝 垃圾回收...

    python 变量命名规范1

    7. **私有实例变量**:以双下划线`__private_var`开头的变量是私有变量,外部直接访问会导致错误。这是Python的封装机制,保护数据不被随意修改。 8. **专有变量**:以双下划线开头和结尾的变量,如`__doc__`、`__...

    python—真假私有变量

    定义私有属性或方法加个__即可(双下划线) 先来定义对象的私有属性(方法一样) class Person(): def __init__(self, name, age): self.name = name self.__age = age def __str__(self): return {},{}.format...

Global site tag (gtag.js) - Google Analytics