Python中类的特殊变量

特殊变量

  • 类似__xx,以双下划线开头的实例变量名,就变成了一个私有变量(private),只有内部可以访问,外部不能访问;
  • 类似__xx__,以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,它不是private变量,下面会介绍Python中的常见特殊变量;
  • 类似_x,以单下划线开头的实例变量名,这样的变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是请把我视为私有变量,不要随意访问”。

内置函数

  • type(),type()函数返回type类型

用法:

import types
type(‘abc‘)==types.StringType
type(u‘abc‘)==types.UnicodeType
type([])==types.ListType
type(str)==types.TypeType

最后这种类型叫做TypeType,所有类型本身就是TypeType。

也可以对函数或者类:

  • isinstance(),判断一个对象是否属于某个类型

一个例子:

class P(object):
    pass

class C(P):
    pass

p = P()
c = C()
print isinstance(p, P)
print isinstance(c, P)
print isinstance(p, C) # False
print isinstance(c, C)

如上,子类实例即是父类类型,也是子类类型,但父类实例不属于子类类型。

isinstance()也可以代替type()的作用:

isinstance(‘a‘, str)
isinstance(u‘a‘, unicode)
isinstance(‘a‘, unicode) #False
  • dir(),获取对象的属性和方法列表
  • getattr(),获取对象的特定属性
  • hasattr(),对象是否存在某个属性
  • setattr(),设置对象的属性

用法:

class P(object):
    name = "cq"
    def __init__(self, age):
        self.age = age

print hasattr(P, "name")    # True
print hasattr(P, "age")     # False
setattr(P, "age", 31)
print getattr(P, "name")    # cq
print getattr(P, "age")     # 31

特殊变量

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica }
p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px }
p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "PingFang SC" }

__doc__

定义文档字符串

__dict__

类的属性列表

__class__

__slots__

对类的实例可以动态的绑定属性和方法,如下:

from types import MethodType

def set_age(self, age):
    self.age = age 

class P(object):
    pass

p = P()
p.name = ‘chenqi‘
p.set_age = MethodType(set_age, p, P)  

p.set_age(31)
print p.name
print p.age

对一个实例添加的属性(或方法)仅在该实例有效,对其它实例不起作用。

如果想让添加的方法对所有实例都生效,可以绑定到类上:

P.set_age = MethodType(set_age, None, P)

最后,__slots__的作用就是限制对类动态绑定的属性范围,例如:

class P(object):
    __slots__ = ("name", "age")
    pass

如上,除了"name"和"age"之外的属性就不能再增加了;

注意:__slots__属性不会继承给子类,仅在当前类生效。

__init__

创建实例的时候,可以调用__init__方法做一些初始化的工作:

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def print_score(self):
        print(‘%s: %s‘ % (self.name, self.score))

与普通的实例方法类似,如果子类不重写__init__,实例化子类时,会自动调用父类的__init__;

如果子类重写了__init__,实例化子类时,则只会调用子类的__init__,此时如果想使用父类的__init__,可以使用super函数,如下:

class P(object):
    def __init__(self, name, score):
        self.name = name
        self.score = name

class C(P):
    def __init__(self, name, score, age):
        super(C, self).__init__(name, score)
        self.age = age 

c = C(‘cq‘, 100, 31) 

__new__

注意:__init__是实例创建之后调用的第一个方法,而__new__更像构造函数,它在__init__之前被调用。

另外,__new__方法是一个静态方法,第一参数是cls,__new__方法必须返回创建出来的实例。

例如,用__new__实现单例模式:

class Singleton(object):
    def __new__(cls):
        # 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象
        if not hasattr(cls, ‘instance‘):
            cls.instance = super(Singleton, cls).__new__(cls)
        return cls.instance

obj1 = Singleton()
obj2 = Singleton()

obj1.attr1 = ‘value1‘
print obj1.attr1, obj2.attr1
print obj1 is obj2

__del__

类似析构函数。

class NewClass(object):
    num_count = 0 

    def __init__(self,name):
        self.name = name
        self.__class__.num_count += 1
        print name,NewClass.num_count

    def __del__(self):
        self.__class__.num_count -= 1
        print "Del",self.name,self.__class__.num_count

a = NewClass("a")
b = NewClass("b")
c = NewClass("c")

del a
del b
del c

注意:用del删除一个对象的时候,不一定会调用__del__,只有在对象的引用计数为零时,__del__()才会被执行。

__enter__

__exit__

这两个方法是用于支持with语句的上下文管理器。

例如让文件句柄支持with语法的实现:

class File(object):
    def __init__(self, file_name, method):
        self.file_obj = open(file_name, method)
    def __enter__(self):
        return self.file_obj
    def __exit__(self, type, value, traceback):
        self.file_obj.close()

with File(‘demo.txt‘, ‘w‘) as opened_file:
    opened_file.write(‘Hola!‘)

__iter__

next

如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。

class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1 # 初始化两个计数器a,b

    def __iter__(self):
        return self # 实例本身就是迭代对象,故返回自己

    def next(self):
        self.a, self.b = self.b, self.a + self.b # 计算下一个值
        if self.a > 100000: # 退出循环的条件
            raise StopIteration();
        return self.a # 返回下一个值

__call__

实例可以像函数一样调用。

class Student(object):

    def __init__(self):
        self.name = "Michael"

    def __call__(self):
        print ‘__call__ called‘

s = Student()
s()

注意:callable()函数可用于判断一个对象是否可调用!

__str__,返回用户看到的字符串

__repr__,返回开发者看到的字符串(用于调试)

# test.py
class P(object):
    def __str__(self):
        return "__str__ called"

    def __repr__(self):
        return "__repr__ called"

p = P() 

可以看下__str__和__repr__的区别:

>>> from test import p
>>> p
__repr__ called
>>> print p
__str__ called

__getitem__

__setitem__

__delitem__

支持下标(或切片)操作的函数,

例如:

class Fib(object):
    def __getitem__(self, n):
        if isinstance(n, int):
            a, b = 1, 1
            for x in range(n):
                a, b = b, a + b
            return a
        if isinstance(n, slice):
            start = n.start
            stop = n.stop
            a, b = 1, 1
            L = []
            for x in range(stop):
                if x >= start:
                    L.append(a)
                a, b = b, a + b
            return L

fib = Fib()
print fib[10]
print fib[0:10]

__getattr__

__getattribute__

__setattr__

__delattr__

支持点操作(即 "对象.属性" 访问方式),

当访问不存在的属性时,才会使用__getattr__  方法.

class Student(object):

    def __init__(self):
        self.name = "Michael"

    def __getattr__(self, attr):
        print ‘__getattr__ called‘
        if attr==‘score‘:
            return 99
        elif attr==‘name‘:
            return "Tom"

s = Student()
print s.score       # 99
print s.name        # Michael

参考文档:

https://infohost.nmt.edu/tcc/help/pubs/python/web/special-methods.html

时间: 2024-10-11 12:48:46

Python中类的特殊变量的相关文章

Python中类的属性的访问控制

因为自己是做.NET的,之前有学习过Python,喜欢这门语言的很多特性,最近又不时看了一会儿,将自己的感受分享给大家,其中也难免会用C#的角度看Python的语法,主要还是讲下Python中类中对属性的访问. 讲到属性访问,都能想到公有,私有,受保护,C#的方法是public private protected,Python中也真心让自己感觉到难以理解. 首先定义一个类(博客园对python代码没着色,大家看图吧) 就个人认识,不一定对,觉得Python是一门动态的语言,很多属性都是动态加上去

Python中类的定义与使用

Python中类的定义与使用 目标: 1.类的定义 2.父类,子类定义,以及子类调用父类 3.类的组合使用 4.内置功能 1.类的定义 代码如下: #!/usr/bin/env python #coding:utf8 class Hotel(object): """docstring for Hotel""" def __init__(self, room, cf=1.0, br=15): self.room = room self.cf = c

python学习笔记2—python文件类型、变量、数值、字符串、元组、列表、字典

python学习笔记2--python文件类型.变量.数值.字符串.元组.列表.字典 一.Python文件类型 1.源代码 python源代码文件以.py为扩展名,由pyton程序解释,不需要编译 [[email protected] day01]# vim 1.py #!/usr/bin/python        print 'hello world!' [[email protected] day01]# python 1.py hello world! 2.字节代码 Python源码文件

学习Python中类及C++类的对比

Python是一种面向对象.解释性语言,所以在Python开发(http://www.maiziedu.com/course/python-px/)里包含有类,因为面向对象语言都有类.今天就简单分享一下Python中类,重点是与C++中的类进行对比. C++中的父类,Python中叫超类(superclass) 创建类 class Person: def setName(self, name): self.name = name def getName(self): return self.na

一入python深似海--变量和对象

一.基本原理 Python中一切都是对象,变量是对象的引用.这是一个普遍的法则.我们举个例子来说,Python是如何来处理的. x = 'blue' y = 'green' z = x 当python执行上面第一句的时候,会在heap中首先创建一个str对象,其文本内容为blue,同时还创建一个名为x的对象引用,x引用的就是这个str对象.第二句也是类似:第三条创建了一个名为z的新对象引用,并将其设置为对象引用x所指向的相同对象.如下图的变化. 所以看出在Python中赋值操作符号"="

python无私有成员变量

python解释器将__init__函数里的__z变量转成 _classname__z了,明白规则后外部依然可以通过实力对象来访问. In [1]: class aa: ...: def __init__(self): ...: self.x = 10 ...: self.y = 11 ...: self.__z = 12 ...: In [2]: a = aa() In [3]: print a.x 10 In [4]: print a.y 11 In [5]: print a.__z ---

<转>Python 参数知识(变量前加星号的意义)

csdn上的牛人就是多,加油 —————————————————————————— 过量的参数 在运行时知道一个函数有什么参数,通常是不可能的.另一个情况是一个函数能操作很多对象.更有甚者,调用自身的函数变成一种api提供给可用的应用. 对于这些情况,python提供了两种特别的方法来定义函数的参数,允许函数接受过量的参数,不用显式声明参数.这些“额外”的参数下一步再解释. 注意args和kwargs只是python的约定.任何函数参数,你可以自己喜欢的方式命名,但是最好和python标准的惯用

python main函数中变量默认为global variable

在python的main函数中的变量默认为全局变量,而其他的def函数中的变量则默认为局部变量. 当然,局部变量会优先于全局变量,在执行formal_print(t_global)语句时便可看出. 测试代码如下: <span style="font-size:18px;">#coding=utf-8 #测试python的全局变量,局部变量的机制 def formal_print(s_global):#常规的传参用法,传递参数进行print,变量名可任意 print &quo

【转】python 修改os环境变量

举一个很简单的例子,如果你发现一个包或者模块,明明是有的,但是会发生这样的错误: >>> from algorithm import *Traceback (most recent call last):  File "<stdin>", line 1, in <module>ImportError: No module named algorithm 那么就应该是环境变量出问题了 okay,来看怎么搞 >>>>>