Python有几个内置方法poperty, classmethod, staticmethod,其中property用来将方法变成属性,而classmethod将一个类的函数变成类方法,staticmethod将类的一个函数变成静态方法。它们是如何使用的,我这里就不讲了,只讲它们可能是怎样实现的。之所以说“可能”,是因为我并不确定,我对Python也只是初学,并且这里讲的可能也只是其中一种实现方式而已。
在讲实现之前我需要稍微介绍一下Python中的Descriptor,Descriptor提供了一种强大的机制来实现对属性的自定义访问。我建议大家都看下Shalabh Chaturvedi的
这篇文章,我这篇博客不过是补充它只是简单提到的东西而已,甚至例子也大部分来源于那篇文章。
下面是一个Descriptor的例子(该例子来源于Shalabh Chaturvedi的文章):
class Desc(object):
def __get__(self, obj, cls=None):
print '__get__: %s' % ((self, obj, cls),)
def __set__(self, obj, val):
print '__set__: %s' % ((self, obj, val),)
def __delete__(self, obj):
print '__delete__: %s' % ((self, obj), )
class C(object):
d = Desc()
cobj = C()
x = cobj.d
cobj.d = 'setting a value'
cobj.__dict__['d'] = 'try to force a value'
x = cobj.d
del cobj.d
x = C.d
C.d = 'setting a value on class'
上面的代码输出:
__get__: (<__main__.Desc object at 0xb74b33cc>, <__main__.C object at 0xb74b342c>, <class '__main__.C'>)
__set__: (<__main__.Desc object at 0xb74b33cc>, <__main__.C object at 0xb74b342c>, 'setting a value')
__get__: (<__main__.Desc object at 0xb74b33cc>, <__main__.C object at 0xb74b342c>, <class '__main__.C'>)
__delete__: (<__main__.Desc object at 0xb74b33cc>, <__main__.C object at 0xb74b342c>)
__get__: (<__main__.Desc object at 0xb74b33cc>, None, <class '__main__.C'>)
我不想作太多解释,只需要注意访问和给cobj.d赋值调用的是Desc的__get__和__set__方法,即使通过__dict__来覆盖cobj的d属性时也是如此。(需要注意的是:Descriptor分为Data Descriptor和Non-Data Descriptor,区别在于Data Descriptor同时实现__get__和__set__方法,而Non-Data只实现了__get__方法,两者的行为不同,上面的例子是Data Descriptor)。
接下来,我们来看如何利用Descriptor来实现Python内置classmethod方法所提供的功能。为了和内置classmethod区别,我将它命名为myclassmethod,它的实现如下:
def myclassmethod(clsmethod):
return ClassMethodDesc(clsmethod)
class ClassMethodDesc(object):
def __init__(self, clsmethod):
self.clsmethod = clsmethod
def __get__(self, obj, cls=None):
def wrap(*args, **kwargs):
return self.clsmethod(cls, *args, **kwargs)
return wrap
myclassmethod返回ClassMethodDesc,它是一个Non-Data Descriptor,只实现了__get__方法,它会返回一个函数,调用这个函数时,它会将调用委托给clsmethod,但第一个参数设置成会传递一个cls参数。它的使用方式和内置的classmethod实现一样,下面是个例子:
class ClassMethodDemo(object):
def cls_method(cls):
print 'You called class %s' % cls
cls_method = myclassmethod(cls_method)
if __name__ == '__main__':
obj = ClassMethodDemo()
obj.cls_method()
ClassMethodDemo.cls_method()
上面代码输出:
You called class <class '__main__.ClassMethodDemo'>
You called class <class '__main__.ClassMethodDemo'>
实现static方法同样很简单,这里就不写了。下面的myproperty方法实现和内置property基本一样的功能,只是它的参数都是必需的,并且只接受getmethod和setmethod两个方法,不再作解释.
def myproperty(getmethod, setmethod):
return PropertyMethodDesc(getmethod, setmethod)
class PropertyMethodDesc(object):
def __init__(self, getmethod, setmethod):
self.getmethod = getmethod
self.setmethod = setmethod
def __get__(self, obj, cls=None):
return self.getmethod(obj)
def __set__(self, obj, val):
return self.setmethod(obj, val)
class PropertyDemo(object):
def get_a(self):
print 'get_a invoked'
return self.__dict__['a']
def set_a(self, val):
print 'set_a as %s' % val
self.__dict__['a'] = val
a = myproperty(get_a, set_a)
if __name__ == '__main__':
obj = PropertyDemo()
obj.a = 5
print obj.a
分享到:
相关推荐
`classproperty`与`classmethod`和`staticmethod`的主要区别在于,`classmethod`接收的第一个参数是类本身,而`staticmethod`则不接收任何特殊参数,两者都处理方法,而非属性。`classproperty`则提供了属性的类...
例如,`@staticmethod` 和 `@classmethod` 装饰器改变类方法的调用方式,`@property` 用于创建属性访问器。 Python 标准库还包含了异常处理机制,使用 `try/except` 语句捕获和处理错误。例如: ```python try: ...
Python还提供了`@property`、`@classmethod`、`@staticmethod` 等装饰器,分别用于创建getter、定义类方法和静态方法。这些装饰器使得类的方法和属性更具面向对象特性,提高了代码的可复用性和可扩展性。 总之,`...
装饰器进阶:property、staticmethod、classmethod源码分析(python代码实现) 装饰器基础 无参装饰器 ''' 假定有一个需求是:打印程序函数运行顺序 此案例打印的结果为: foo1 function is starting foo2 ...
5. **特性(property)**:在Python中,property是用于封装类的属性,它将数据访问逻辑包装在getter和setter方法中,以提供数据验证和控制。通过使用`@property`、`@name.setter`等装饰器可以创建特性。 6. **使用...
描述符可以控制对属性的访问,并且被用来实现Python的@property装饰器、@classmethod、@staticmethod和__slots__等特性。 属性查找(Attribute Lookup):属性查找是Python处理实例和类属性访问的过程。当查找实例x...
1. 装饰器:用于扩展或修改函数、类的功能,如 @classmethod、@staticmethod、@property 等。 2. 上下文管理器:通过 with 语句进行资源的自动获取和释放,如文件操作。 3. 面向切面编程(AOP):利用装饰器实现切面...
此外,Python的标准库提供了许多内置的面向对象工具,比如`__slots__`用于节省内存,`property`用于创建属性的访问器,以及`@classmethod`和`@staticmethod`用于定义类方法和静态方法。这些都是在实际开发中会经常...
下面这些是什么意思:`@classmethod`,`@staticmethod`,`@property`? - **`@classmethod`**: 类方法,第一个参数通常为类本身(`cls`)。 - **`@staticmethod`**: 静态方法,没有额外的参数。 - **`@property`**: ...
问题,另外还引入了一些新的概念,比如 classmethod, staticmethod, super, Property 等。因此理解 descriptor 有助于更好地了解 Python 的运行机制。 那么什么是 descriptor 呢? 简而言之:descriptor 就是一类...
### Python面向对象编程详解 #### 一、创建类和对象 面向对象编程(Object-Oriented Programming, OOP)是一种程序设计思想,它把对象作为程序的基本单元,一个对象包含了数据和对这些数据的操作方法。在Python中,...
Python的`staticmethod`和`classmethod`装饰器允许我们在不绑定实例或类的情况下调用方法,这在访问控制中有时也会发挥作用,特别是在设计模式如工厂方法中。 8. 私有变量的访问: 尽管Python没有硬性的私有变量...
使用`@decorator`语法,如`@staticmethod`、`@classmethod`、`@property`等。 11. **上下文管理器**:使用`with`语句可以确保资源的正确释放,如打开文件后自动关闭。 12. **多线程与多进程**:Python的`threading...
Python中的内置装饰器包括@classmethod、@staticmethod和@property。@classmethod用于类方法,它接收类对象作为第一个参数;@staticmethod不接收类或实例作为参数,用于定义与类相关的功能;@property用于属性的获取...
深入理解`@staticmethod`、`@classmethod`和`@property`等内置装饰器的源码,有助于我们编写自己的高效装饰器。 Python的标准库提供了大量预先封装好的功能,如网络通信、文件操作、数据结构等。通过查看标准库的...
`property`可以配合`@classmethod`和`@staticmethod`装饰器一起使用,实现对属性的获取和设置操作。例如: ```python class Money: def __init__(self): self.__money = 0 @property def money(self): ...
同时,你还可以使用Python的`@property`装饰器来创建只读属性,或者提供额外的检查和控制。 **类的常见属性**包括实例变量(通过`self`在`__init__`中初始化)、类变量(属于类而非实例,所有实例共享同一份数据)...
通过`@classmethod`和`@staticmethod`,类装饰器可以处理类对象和实例对象。 13. 内存管理机制:Python采用垃圾回收机制自动管理内存,当一个对象没有引用时,垃圾回收器会将其释放。此外,Python还有引用计数和分...
Python还提供了一些内置的装饰器,例如`@staticmethod`和`@classmethod`,它们分别用于定义静态方法和类方法。此外,`@property`装饰器用于将一个方法转化为属性,提供访问控制和计算属性的功能。 装饰器还可以层层...