python基础-对象高级特性

一、实例绑定:

二、使用__slots__:

三、@property:python内置装饰器 decorator

四、多重继承:Mixin

五、定制类:

  1、 __str__ 和 __repr__: 打印一个实例

  2、 __iter__: 被用于 for ... in循环

  3、__getitem__ :现得像list那样按照下标取出元素,需要实现__getitem__()方法

  4、__getattr__ : 动态返回一个属性

  5、__call__ : 对实例本身进行调用

六、使用元类:metaclass

  1、type(): 通过type()函数创建类,而无需通过class

  2、metaclass: 除了使用type()动态创建类以外,要控制类的创建行为,还可以使用metaclass。--元类.

  3、metaclass动态创建ORM:动态创建的好处

  4、类属性和实例属性:区别

-----------------------------------------------------------------------------------------------------------------

一、实例绑定:

  动态的给一个实例绑定属性和方法:

>>> class Student(object):
...   pass
...
>>> s = Student()
>>> s.name=‘Micheal‘  #动态给实例绑定一个属性
>>> print s.name
Micheal
>>> def set_age(self,age):  #定义一个函数作为实例方法
...   self.age = age
...
>>> from types import MethodType
>>> s.set_age = MethodType(set_age,s,Student)   #给实例绑定一个方法
>>> s.set_age(25)  # 调用实例方法
>>> s.age    #测试结果
25

  注意:给一个实例绑定的方法,对另一个实例是不起作用的:

>>> s2 = Student() # 创建新的实例
>>> s2.set_age(25) # 尝试调用方法
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: ‘Student‘ object has no attribute ‘set_age‘

  给class绑定的方法,所有实例可用:

>>> def set_score(self, score):
...     self.score = score
...
>>> Student.set_score = MethodType(set_score, None, Student)
>> s.set_score(100)
>>> s.score
100
>>> s2.set_score(99)
>>> s2.score
99

二、使用__slots__:

  现在有一个需求:限制class的属性(包括变量函数),那么在类中可以定义 __slots__:

>>> class Student(object):
...     __slots__ = (‘name‘, ‘age‘) # 用tuple定义允许绑定的属性名称
...
>>> s = Student() # 创建新的实例
>>> s.name = ‘Michael‘ # 绑定属性‘name‘
>>> s.age = 25 # 绑定属性‘age‘
>>> s.score = 99 # 绑定属性‘score‘
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: ‘Student‘ object has no attribute ‘score‘

  注意:__slots__定义的属性仅对当前类起作用,对继承的子类是不起作用的:

>>> class GraduateStudent(Student):
...     pass
...
>>> g = GraduateStudent()
>>> g.score = 9999

  除非在子类中也定义__slots__,这样,子类允许定义的属性就是自身的__slots__加上父类的__slots__

三、@property,python内置装饰器 decorator

  既能检查参数,又可以用类似属性这样简单的方式来访问类的变量:

class Student(object):

    @property
    def score(self):      #相当于getter,,,property会自动生成一个socre.setter
        return self._score

    @score.setter
    def score(self, value):  #相当于setter,,,弱想只读属性,即不声明次函数和decorator即可.
        if not isinstance(value, int):
            raise ValueError(‘score must be an integer!‘)
        if value < 0 or value > 100:
            raise ValueError(‘score must between 0 ~ 100!‘)
        self._score = value
>>> s = Student()
>>> s.score = 60 # OK,实际转化为s.set_score(60)
>>> s.score # OK,实际转化为s.get_score()
60
>>> s.score = 9999
Traceback (most recent call last):
  ...
ValueError: score must between 0 ~ 100!

四、多重继承:Mixin

  Mixin的目的就是给一个类增加多个功能,这样,在设计类的时候,优先考虑通过多重继承来组合多个Mixin的功能,而不是设计多层次的复杂的继承关系。

  比如,编写一个多进程模式的TCP服务,定义如下:

class MyTCPServer(TCPServer, ForkingMixin):
    pass

  编写一个多线程模式的UDP服务,定义如下:

class MyUDPServer(UDPServer, ThreadingMixin):
    pass

  不需要复杂而庞大的继承链,只要选择组合不同的类的功能,就可以快速构造出所需的子类。

五、定制类

  形如__xxx__的变量或者函数名,在Python中有特殊用途,比如:__slots__,__len__()方法作用于len()函数。

  1、 __str__ 和 __repr__ 打印一个实例

>>> class Student(object):
...     def __init__(self, name):
...         self.name = name
...     def __str__(self):
...         return ‘Student object (name: %s)‘ % self.name
...     __repr__ = __str__    #按变量打印也如 __str__ 函数
...
>>> print Student(‘Michael‘)  #这里调用 __str__
Student object (name: Michael)
>>> s = Student(‘Michael‘)
>>> s                #这里调用 __repr__
Student object (name: Michael)

  2、 __iter__ 被用于 for ... in循环

    实现__iter__()方法,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 # 返回下一个值
>>> for n in Fib():
...     print n
...
1
1
2
3
5
...
46368
75025

  3、__getitem__ :现得像list那样按照下标取出元素,需要实现__getitem__()方法

class Fib(object):
    def __getitem__(self, n):
        a, b = 1, 1
        for x in range(n):
            a, b = b, a + b
        return a
>>> f = Fib()
>>> f[0]
1
>>> f[1]
1
>>> f[2]
2
>>> f[3]
3
>>> f[10]
89
>>> f[100]
573147844013817084101

      list中切片实现方法:f[a:b], 切片对象为slice.

>>> 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
...
>>> f = Fib()
>>> f[0:5]
[1, 1, 2, 3, 5]
>>> Fib()[2:7]
[2, 3, 5, 8, 13]

    以上还没有对负数,step做处理,如果把对象看成dict对象,还应该处理传入key的情况,key的类型为str.

    与之对应的还有 __setitem__(),把对象视作list或dict来对集合赋值,__delitem__()方法,用于删除某个元素.

  4、__getattr__ : 动态返回一个属性

    当调用不存在的属性时,Python解释器会试图调用__getattr__(self, ‘score‘)来尝试获得属性,这样,就有机会返回score的值.

>>> class Student(object):
...   def __init__(self):
...     self.name=‘Michael‘
...   def __getattr__(self,attr):  #attr 为临时变量,调用时为存存储了str类型的属性名字.
...     if attr==‘score‘:
...       return 99
...
>>> s = Student()>>> s.score
99

    返回函数也可以:

>>> class Teacher():
...   def __getattr__(self,attr):
...     if attr == ‘age‘:
...       return lambda:25
...
>>> t = Teacher()
>>> t.age    #该属性为一个匿名方法.
<function <lambda> at 0x0059D0F0>
>>> t.age()
25

    注意:在没有找到属性的情况下,才调用__getattr__(selt,attr) ,定义该属性后,其他属性都会返回None,那么按照约定应该返回AttributeError.

class Student(object):

    def __getattr__(self, attr):
        if attr==‘age‘:
            return lambda: 25
        raise AttributeError(‘\‘Student\‘ object has no attribute \‘%s\‘‘ % attr)

    这种完全动态调用的特性有什么实际作用呢?作用就是,可以针对完全动态的情况作调用。

    例子:

    现在很多网站都搞REST API,比如新浪微博、豆瓣啥的,调用API的URL类似:

http://api.server/user/friends
http://api.server/user/timeline/list

    如果要写SDK,给每个URL对应的API都写一个方法,那得累死,而且,API一旦改动,SDK也要改。

    利用完全动态的__getattr__,我们可以写出一个链式调用:

>>> class Chain(object):
...      def __init__(self,path=‘‘):
...        self._path = path
...      def __getattr__(self,path):
...        return Chain(‘%s/%s‘ %(self._path,path))
...      def __str__(self):
...        return self._path
...      __repr__ = __str__
...
>>> Chain().status.user.timeline.list
/status/user/timeline/list
>>> Chain().s.as.sd            #发现在这种方式中属性不能为python中的关键字.是个坑喔.这个坑可以解决,用下面问题的实现就可解决.
  File "<stdin>", line 1
    Chain().s.as.sd
               ^
SyntaxError: invalid syntax
>>> Chain().s
/s
>>> Chain().s.a
/s/a
>>> Chain().s.ads.a
/s/ads/a

    还有些REST API会把参数放到URL中,比如GitHub的API:该题链接.

GET /users/:user/repos    #需要把:user替换为实际用户名

    写出这样的链式调用:

Chain().users(‘michael‘).repos

    我的答案:

class Chain(object):
    def __init__(self, path=‘‘):
        self._path = path
    def __getattr__(self, path):
        return Chain(‘%s/%s‘ % (self._path, path))

    def __str__(self):
        return self._path

    def __getitem__(self, path):      #支持下标Chain().users[‘Michael‘].repos
        return Chain(‘%s/%s‘ % (self._path, path))

    def __call__(self,name):
        return Chain(‘%s/%s‘ % (self._path, name))

    # def users(self,name=‘default‘):   #仅针对Chain().users(‘Michael‘).repos起作用,不够灵活.
    #     return Chain(‘/users/‘+name)

    __repr__ = __str__
>>> Chain().users(‘michael‘).repos
GET /users/michael/repos
>>> Chain().a.b.c
GET /a/b/c
>>>Chain().users[‘michael‘].repos
/users/michael/repos
>>>Chain().users(‘as‘).repos   #关键字也不怕
/users/as/repos

  5、__call__ : 对实例本身进行调用

    任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用:

>>> class Student(object):
...   def __init__(self,name):
...     self.name = name
...   def __call__(self):
...     print(‘My name is %s.‘% self.name)
...
>>> s= Student(‘Michael‘)
>>> s()
My name is Michael:

    判断一个对象是否能被调用,能被调用的对象就是一个Callable对象,比如函数和我们上面定义的带有__call()__的类实例

>>> s= Student(‘Michael‘)
>>> s()
My name is Michael.
>>> callable(s)
True
>>> callable(filter)  #filter为内置函数呢,居然是callable对象.
True
>>> callable(int)
True
>>> callable(str)
True

 六、使用元类

  1、type(): 通过type()函数创建类,而无需通过class 定义:

>>> def fn(self,name=‘world‘):
...   print(‘Hello,%s.‘ % name)
...
>>> Hello = type(‘Hello‘,(object,),dict(hello=fn))  #使用type动态创建出类.
>>> h = Hello()
>>> h.hello()
Hello,world.
>>> print (type(Hello))
<type ‘type‘>
>>> print(type(h))
<class ‘__main__.Hello‘>

    创建一个class对象,type()函数依次传入3个参数:

    1.class的名称;--str

    2.继承的父类集合, --tuple

    3.class的方法名称与函数绑定 --dict , {name = func}

    通过type()函数创建的类和直接写class是完全一样的,因为Python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用type()函数创建出class

  2、metaclass: 除了使用type()动态创建类以外,要控制类的创建行为,还可以使用metaclass。--元类.

    先定义metaclass,就可以创建类,最后创建实例。

    metaclass允许你创建类或者修改类的定义.可以把类看成是metaclass创建出来的“实例

    metaclass的类名总是以Metaclass结尾,以便清楚地表示这是一个metaclass

    一个简单的例子,这个metaclass可以给我们自定义的MyList增加一个add方法:

# metaclass是创建类,所以必须从`type`类型派生:
>>> class ListMetaclass(type):
...   def __new__(cls,name,bases,attrs):
...     attrs[‘__slots__‘] = (‘ad‘,‘add‘)  #限制创建类的属性
...     attrs[‘add‘] = lambda self,value:self.append(value)   #继承自list,所以有append方法.
...     attrs[‘address‘] = 2  #该属性为read-only,,因为attrs[‘__slots__‘]中的tuple没有定义.
...     return type.__new__(cls,name,bases,attrs)    #使用type来创建类.
...
>>> class MyList(list):    #继承自list
...   __metaclass__ = ListMetaclass    # 指示使用ListMetaclass来 创建 类 达到 定制 的 效果
...
>>> L = MyList()
>>> L.add(1)
>>> L
[1]
>>>L.ad = 2
>>>L.ad
2
>>>L.addss = 2
AttributeError: ‘MyList‘ object has no attribute ‘addss‘
>>>L.address = 3
AttributeError: ‘MyList‘ object attribute ‘address‘ is read-only

    __metaclass__ = ListMetaclass语句,指示Python解释器在创建MyList时,要通过ListMetaclass.__new__()来创建,在此,我们可以修改类的定义,父类继承,比如,加上新的方法,然后,返回修改后的定义。

    可能有的同学对__init__和__new__感到困惑: 参考

Use __new__ when you need to control the creation of a new instance.
Use __init__ when you need to control initialization of a new instance.

    __new__()方法接收到的参数依次是:

      1.当前准备创建的类的对象:--typeType

      2.类的名字:--str

      3.类继承的父类集合:--tuple

      4.类的属性集合:--dict

  3、metaclass动态创建ORM:

    动态修改有什么意义?直接在MyList定义中写上add()方法不是更简单吗?正常情况下,确实应该直接写,通过metaclass修改纯属变态。

    但是,总会遇到需要通过metaclass修改类定义的。ORM就是一个典型的例子。

    ORM全称“Object Relational Mapping”,即对象-关系映射,就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表,这样,写代码更简单,不用直接操作SQL语句。

    要编写一个ORM框架,所有的类都只能动态定义,因为只有使用者才能根据表的结构定义出对应的类来。

    尝试编写一个ORM框架。

    编写底层模块的第一步,就是先把调用接口写出来。比如,使用者如果使用这个ORM框架,想定义一个User类来操作对应的数据库表User,期待写出这样的代码:

class User(Model):
    # 定义类的属性到列的映射:
    id = IntegerField(‘id‘)
    name = StringField(‘username‘)
    email = StringField(‘email‘)
    password = StringField(‘password‘)

# 创建一个实例:
u = User(id=12345, name=‘Michael‘, email=‘[email protected]‘, password=‘my-pwd‘)
# 保存到数据库:
u.save()

    其中,父类Model和属性类型StringFieldIntegerField是由ORM框架提供的,剩下的魔术方法比如save()全部由metaclass自动完成。虽然metaclass的编写会比较复杂,但ORM的使用者用起来却异常简单。

    现在,我们就按上面的接口来实现该ORM。

    首先来定义Field类,它负责保存数据库表的字段名和字段类型:

class Field(object):
    def __init__(self, name, column_type):
        self.name = name
        self.column_type = column_type
    def __str__(self):
        return ‘<%s:%s>‘ % (self.__class__.__name__, self.name)

    在Field的基础上,进一步定义各种类型的Field,比如StringFieldIntegerField等等:

class StringField(Field):
    def __init__(self, name):
        super(StringField, self).__init__(name, ‘varchar(100)‘)

class IntegerField(Field):
    def __init__(self, name):
        super(IntegerField, self).__init__(name, ‘bigint‘)

    下一步,就是编写最复杂的ModelMetaclass了:

class ModelMetaclass(type):
    def __new__(cls,name,bases,attrs):            #元类.控制和创建类.
        if name==‘Model‘:
            return type.__new__(cls,name,bases,attrs)
        mapping = dict()                        #在类中增加一个dict类型的映射 mapping
        for k,v in attrs.iteritems():            #遍历内嵌的属性,这里的属性值为另两种类型(StringField 和 IntergerField)
            if isinstance(v,Field):
                print(‘映射:%s==>%s‘ %(k,v) )
                mapping[k] = v
                print‘属性名:%s,列名:%s,类型:%s‘ %(k,v.name,v.column_type)
        for k in mapping.iterkeys():
            attrs.pop(k)    #删除原有类属性名,避免混淆,统一存在mapping映射中.
        attrs[‘__table__‘] = name #假设表名和类名一致.
        attrs[‘__mapping__‘] = mapping  #保存属性和列以及类型的映射关系.
        return type.__new__(cls,name,bases,attrs)

    以及基类Model

#实体类基础
class Model(dict):
    __metaclass__ = ModelMetaclass

    def __init__(self,**kw):
        super(Model,self).__init__(**kw)        #这里利用dict的__init__()方法.
    def __getattr__(self,key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError(r"‘Model‘ ojbect has no attribute ‘%s‘" % key)
    def __setattr__(self,key,value):
        self[key] = value

    def save(self):
        fields = []
        params = []
        args = []
        for k,v in self.__mapping__.iteritems():  #mapping为一个dict.并且在metaclass中定义.
            fields.append(v.name)                    #添加定义的列名
            #获取创建实例时根据列名保存的参数.
            parame = getattr(self,k,None)
            if parame is None:                        #parame不能为None,‘‘.join()不支持None
                raise TypeError(‘parame %s NoneType Found‘ % k)
            if isinstance(parame,int):                #判断获取的值是否是int,转化为str,否则下面的join函数int类型会解析错误.
                params.append(str(parame))
            else:
                params.append(parame)
        sql = ‘insert into %s (%s) values (%s)‘ % (self.__table__,‘,‘.join(fields),‘,‘.join(params))
        print(‘SQL:%s‘ % sql)

    当用户定义一个class User(Model)时,Python解释器首先在当前类User的定义中查找__metaclass__,如果没有找到,就继续在父类Model中查找__metaclass__,找到了,就使用Model中定义的__metaclass__ModelMetaclass来创建User类,也就是说,metaclass可以隐式地继承到子类,但子类自己却感觉不到。

    下面我们定义上面的User类继承自Model

class User(Model):
    #定义类的属性到列的映射,
    id = IntergerField(‘ID‘)
    name = StringField(‘USERNAME‘)
    email = StringField(‘EMAIL‘)
    password =StringField(‘PASSWD‘)

    测试:

u = User(id=12345,name=‘Michael‘,email=‘[email protected]‘,password=‘my-pwd‘) #根据类中定义的列,创建实例.
    u.save()
映射:email==><StringField:EMAIL>
属性名:email,列名:EMAIL,类型:varchar(100)
映射:password==><StringField:PASSWD>
属性名:password,列名:PASSWD,类型:varchar(100)
映射:id==><IntergerField:ID>
属性名:id,列名:ID,类型:bigint
映射:name==><StringField:USERNAME>
属性名:name,列名:USERNAME,类型:varchar(100)
SQL:insert into User (PASSWD,EMAIL,USERNAME,ID) values (my-pwd,[email protected],Michael,12345)
[Finished in 0.1s]

    详情参考:这里

  4、类属性和实例属性:

    直接在class中定义的是类属性:

class Student(object):
    name = ‘Student‘

    实例属性必须通过实例来绑定,比如self.name = ‘xxx‘。测试一下:

>>> # 创建实例s:
>>> s = Student()
>>> # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性:
>>> print(s.name)
Student
>>> # 这和调用Student.name是一样的:
>>> print(Student.name)
Student
>>> # 给实例绑定name属性:
>>> s.name = ‘Michael‘
>>> # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性:
>>> print(s.name)
Michael
>>> # 但是类属性并未消失,用Student.name仍然可以访问:
>>> print(Student.name)
Student
>>> # 如果删除实例的name属性:
>>> del s.name
>>> # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了:
>>> print(s.name)
Student

    因此,在编写程序的时候,千万不要把实例属性和类属性使用相同的名字。

    在上面编写的ORM中,ModelMetaclass删除掉了User类的所有类属性,目的就是避免造成混淆。

时间: 2024-10-15 15:55:56

python基础-对象高级特性的相关文章

Python面向对象编程高级特性

***这里还是根据网上资料,主要是廖雪峰老师的教程学习的笔记,主要介绍python面向对象的高级特性,笔记不全,只是记录自己觉得容易出错的地方*** 1.python作为一种动态语言,他的动态绑定机制允许在运行过程中动态的给class或者对象实例添加方法和属性,这个在静态语言中比如java是很难做到的: 1)动态绑定属性: 2)动态绑定方法 给一个实例绑定的方法对于其他实例和类都是不可见的:(这里也说明给一个实例动态绑定方法必须用MethodType(func, instance)) 但是给类绑

Python的一些高级特性

内容基本上来自于廖雪峰老师的blog相当于自己手打了一遍,加强加强理解吧. http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000 Python的一些高级特性 Slot python是动态语言,所谓动态,就是可以先创建类的实例,之后再动态绑定属性或方法,比如下边这个例子: class Student(object) pass s=Student() s.name="asd" 注

Python自动化 【第七篇】:Python基础-面向对象高级语法、异常处理、Scoket开发基础

本节内容: 1.     面向对象高级语法部分 1.1   静态方法.类方法.属性方法 1.2   类的特殊方法 1.3   反射 2.     异常处理 3.     Socket开发基础 1.     面向对象高级语法部分 1.1   静态方法.类方法.属性方法 1)   静态方法 通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法.普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访

Redis基础、高级特性与性能调优

本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍.之后概览Redis提供的高级能力,并在部署.维护.性能调优等多个方面进行更深入的介绍和指导.本文适合使用Redis的普通开发人员,以及对Redis进行选型.架构设计和性能调优的架构设计人员. 目录 概述 Redis的数据结构和相关常用命令 数据持久化 内存管理与数据淘汰机制 Pipelining 事务与Scripting Redis性能调优 主从复制与集群分片 Redis Java客户端的

python自测——高级特性

高级特性 70.函数装饰器有什么作用?请列举说明?71.Python 垃圾回收机制?72.魔法函数 __call__怎么使用?73.如何判断一个对象是函数还是方法?[email protected] 和@staticmethod 用法和区别75.Python 中的接口如何实现?76.Python 中的反射了解么?77.metaclass 作用?以及应用场景?78.hasattr() getattr() setattr()的用法79.请列举你知道的 Python 的魔法方法及用途.80.如何知道一

python基础--面向对象高级、异常处理、网络编程

一.面向对象高级 1.接口与归一化设计 接口只是定义了一些方法,而没有去实现,多用于程序设计时,只是设计需要有什么样的功能,但是并没有实现任何功能,这些功能需要被另一个类(B)继承后,由 类B去实现其中的某个功能或全部功能. 在python中接口由抽象类和抽象方法去实现,接口是不能被实例化的,只能被别的类继承去实现相应的功能 归一化让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度. 归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的

Python之路,Day8 - Python基础 面向对象高级进阶与socket基础

类的成员 类的成员可以分为三大类:字段.方法和属性 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段.而其他的成员,则都是保存在类中,即:无论对象的多少,在内存中只创建一份. 一.字段 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, 普通字段属于对象 静态字段属于类 class Province: # 静态字段 country = '中国'def __init__(self, name): #

Redis 基础、高级特性与性能调优

本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍.之后概览Redis提供的高级能力,并在部署.维护.性能调优等多个方面进行更深入的介绍和指导. 本文适合使用Redis的普通开发人员,以及对Redis进行选型.架构设计和性能调优的架构设计人员. 目录 概述 Redis的数据结构和相关常用命令 数据持久化 内存管理与数据淘汰机制 Pipelining 事务与Scripting Redis性能调优 主从复制与集群分片 Redis Java客户端

python:函数的高级特性

很多语言中,都允许把函数本身做为参数,传递给其它参数:即所谓的高阶函数.python中也有类似特性: 一.map/reduce.filter.sorted hadoop里的map-reduce思想在python里已经变成内置函数了.map是将某个函数逐一作用于列表中的每个元素.reduce则先从列表中取头2个元素,传到指定函数,然后将计算结果与余下元素依次重复,直到List处理完. 1.1 map示例:(将List中的所有元素*10) def fn_map(x): print("fn_map-&