Python 中的 classmethod may be static和 staticmethod may be static有什么具体用途

Python 中的 classmethod 和 staticmethod 有什么具体用途_百度知道
Python 中的 classmethod 和 staticmethod 有什么具体用途
提问者采纳
可以当做普通方法一样调用 ,而不是类的实例staticmethod将class中的方法变成静态方法,自动传给方法的第一个参数是类classmethod将方法变成类方法
来自团队:
其他类似问题
为您推荐:
python的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&Python 学习入门(37)―― @classmethod函数
@classmethod : 类方法@staticmethod : 静态方法类方法和静态方法的调用一样,都是通过类就可以直接调用。区别:类方法,需要传入该类,定义类方法的时候要传一个默认的参数cls。静态方法则不用。示例:#!/usr/bin/env python
# -*- coding: utf-8 -*-
# blog.ithomer.net
class Test(object):
def __init__(self, _x):
self._x = _x
print("Test.__init__")
@classmethod
def class_method(cls):
print("class_method")
@staticmethod
def static_method():
print("static_method")
@classmethod
def getPt(cls):
cls.class_method()
cls.static_method()
if "__main__" == __name__:
Test.class_method()
# class_method
Test.static_method()
# static_method
Test.getPt()
# class_method
static_method
t = Test(22)
# Test.__init__
t.class_method()
# class_method
t.static_method()
# static_method
print Test.x
print Test._x
print t._x
# 'Test' object has no attribute 'getPr'运行结果:class_method
static_method
class_method
static_method
Test.__init__
class_method
static_method
Traceback (most recent call last):
File "/home/homer/workspace/my/com/connmiliao.py", line 40, in
AttributeError: 'Test' object has no attribute 'getPr'示例:@property,@staticmethod,@classmethod #!/usr/bin/env python
# -*- coding: utf-8 -*-
# blog.ithomer.net
class MyClass(object):
def __init__(self):
print '__init__'
self._name = 'blog.ithomer.net'
@staticmethod
def static_method():
print 'This is a static method!'
def test(self):
print 'call test'
@classmethod
def class_method(cls):
print 'cls: ',cls
print 'cls.name: ',cls.name
print 'cls.static_method(): ',cls.static_method()
instance = cls()
print 'instance.test(): ',instance.test()
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
if __name__ == '__main__':
MyClass.static_method()
MyClass.class_method()
mc = MyClass()
print mc.name
mc.name = 'forum.ithomer.net'
print mc.name运行结果:This is a static method!cls:
cls.static_method():
This is a static method!None__init__instance.test():
call testNone__init__blog.ithomer.netforum.ithomer.net
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'staticmethod 基本上和一个全局函数差不多,只不过可以通过类或类的实例对象
(python里光说对象总是容易产生混淆, 因为什么都是对象,包括类,而实际上
类实例对象才是对应静态语言中所谓对象的东西)来调用而已, 不会隐式地传入
任何参数。这个和静态语言中的静态方法比较像。
classmethod 是和一个class相关的方法,可以通过类或类实例调用,
并将该class对象(不是class的实例对象)隐式地 当作第一个参数传入。
就这种方法可能会比较奇怪一点,不过只要你搞清楚了python里class也是个真实地
存在于内存中的对象,而不是静态语言中只存在于编译期间的类型。
正常的方法 就是和一个类的实例对象相关的方法,通过类实例对象进行调用,
并将该实例对象隐式地作为第一个参数传入,这个也和其它语言比较像。
可如下示例:
1 #!/usr/bin/python
2 2.#coding:utf-8
4 4.#author:
5 5.#date:
7 7.class Person:
def __init__(self):
print "init"
@staticmethod
def sayHello(hello):
if not hello:
hello='hello'
print "i will sya %s" %hello
@classmethod
def introduce(clazz,hello):
clazz.sayHello(hello)
print "from introduce method"
def hello(self,hello):
self.sayHello(hello)
print "from hello method"
29 29.def main():
Person.sayHello("haha")
Person.introduce("hello world!")
#Person.hello("self.hello") #TypeError: unbound method hello() must be called with Person instance as first argument (got str instance instead)
print "*" * 20
p = Person()
p.sayHello("haha")
p.introduce("hello world!")
p.hello("self.hello")
40 40.if __name__=='__main__':
1 i will sya haha
2 2.i will sya hello world!
3 3.from introduce method
4 4.********************
6 6.i will sya haha
7 7.i will sya hello world!
8 8.from introduce method
9 9.i will sya self.hello
10 10.from hello method
Views(...) Comments()trackbacks-0
staticmethod
首先来看@staticmethod,这个装饰器很好理解,就是让类中的方法变成一个普通的函数(因为是普通函数,并没有绑定在任何一个特定的类或者实例上。所以与不需要对象实例化就可以直接调用)。可以使用类或者类的实例调用,并且没有任何隐含参数的传入,所以不需要self(参数名是随便定的)。
&&& class C(object):
@staticmethod
def add(a,b):
return a+b
def get_weight(self):
return self.add(1,2)
&function add at 0x1d32668&
&&& C().add
&function add at 0x1d32668&
&&& C.get_weight
&unbound method C.get_weight&
1、当一个函数逻辑上属于一个类又不依赖与类的属性的时候,可以使用 @staticmethod。
2、使用 @staticmethod 可以避免每次使用的时都会创建一个对象的开销。
3、@staticmethod 可以使用类和类的实例调用。但是不依赖于类和类的实例的状态。
classmethod
再看@classmethod,我们对比下加与不加装饰前后函数
不加装饰前
&&& class C(object):
weight = 12
def get_weight(self):
print self
&&& C.get_weight
&unbound method C.get_weight&
&&& C().get_weight
&bound method C.get_weight of &__main__.C object at 0x25d7b10&&
&&& C().get_weight()
&__main__.C object at 0x25d7a50&
&&& myc = C()
&&& myc.get_weight
&bound method C.get_weight of &__main__.C object at 0x25d7a50&&
&&& myc.get_weight()
&__main__.C object at 0x25d7a50&
通过例子知道,C().get_weight和myc.get_weight都是绑定在对象C的一个实例上的。(e.g. &bound method C.get_weight of &__main__.C object at 0x25d7b10&&)
顺便通过下面的代码,看下get_weight的self到底接收的是什么:
#继续上面的代码&&& C.get_weight()
Traceback (most recent call last):
File "&stdin&", line 1, in &module&
TypeError: unbound method get_weight() must be called with C instance as first argument (got nothing instead)
&&& C.get_weight(C())
#将C的一个实例显示传递给self
&__main__.C object at 0x25d7b50&
&&& myc.get_weight()
#myc.get_weight()隐藏了第一个参数myc
&__main__.C object at 0x25d7a50&
调用的实例隐藏的作为一个参数self传递过去了,self 只是一个普通的参数名称(参数名是随便定的),不是关键字。
加@classmethod装饰后
&&& class C(object):
weight = 12
@classmethod
def get_weight(cls):
&&& C.get_weight
&bound method type.get_weight of &class '__main__.C'&&
&&& C().get_weight
&bound method type.get_weight of &class '__main__.C'&&
&&& myc = C()
&&& myc.get_weight
&bound method type.get_weight of &class '__main__.C'&&
&&& myc.get_weight()
&class '__main__.C'&&&& C.get_weight()&class '__main__.C'&
可以看出,C类和C类的实例都能调用 get_weight 而且调用结果完全一样。 我们看到 weight 是属于 C类的属性,当然也是C的实例的属性(元对象__get__机制)。
再看一下get_weight的参数cls到底接收的是什么,可以看到C.get_weight()和myc.get_weight()接收的都是C类(e.g. &class '__main__.C'&&)而不是C类的实例,cls只是一个普通的函数参数,调用时隐含的传递过去。
1、classmethod 是类对象与函数的结合。
2、可以使用类和类的实例调用,但是都是将类作为隐含参数传递过去。
3、使用类来调用 classmethod 可以避免将类实例化的开销。
==============================================================================
@staticmethod 装饰器会让 foo 的 __get__ 返回一个函数,而不是一个方法。看下面的例子
&&& class C(object):
def foo(self):
&unbound method C.foo&
&&& C().foo
&bound method C.foo of &__main__.C object at 0xb76ddcac&&
所谓 bound method ,就是方法对象的第一个函数参数绑定为了这个类的实例(所谓 bind )。这也是那个 self 的由来。
那,我们加入@staticmethod之后:
&&& class C(object):
@staticmethod
def foo():
&function foo at 0xb76d056c&
&&& C.__dict__['foo'].__get__(None, C)
&function foo at 0xb76d056c&
装饰器会让 foo 的 __get__ 返回一个函数,而不是一个方法。
参考资料:
Stackoverflow上的Python问题精选&
Python中的method&
python中的元类编程&
阅读(...) 评论()}

我要回帖

更多关于 method may be static 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信