首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > perl python >

python中的静态方法跟类方法有什么根本的不同

2012-12-30 
python中的静态方法和类方法有什么根本的不同?请教静态方法和类方法有什么根本的不同?因为它们实在太相似

python中的静态方法和类方法有什么根本的不同?
请教静态方法和类方法有什么根本的不同?因为它们实在太相似了


#coding:utf-8
class A(object):
    "This ia A Class"

    @staticmethod
    def Foo1():
        print("Call static method foo1()\n")

    @classmethod
    def Foo2(cls):
        print("Call class method foo2()")
        print("cls.__name__ is ",cls.__name__)

A.Foo1();
A.Foo2();


结果是:

Call static method foo1()

Call class method foo2()
cls.__name__ is  A


除了在定义类方法时需要一个参数外,我觉得静态方法和类方法没什么太大的区别.
可不可以认为类方法其实就是静态方法?
它们两个在应用方面有什么不同呢?哪些场景应用中只能用其中的一种而不能用另一种?

[解决办法]
实例方法隐含的参数为类实例,而类方法隐含的参数为类本身。
静态方法无隐含参数,主要为了类实例也可以直接调用静态方法。
所以逻辑上类方法应当只被类调用,实例方法实例调用,静态方法两者都能调用。
注意啊只是逻辑上啊,其实python的类模型实现上灵活而蛋疼着。
这些玩意基本都是为了隐含参数而搞出来的鬼名堂。
了解这点只要参数个数匹配,python就允许你"胡扯"了。


class Test(object):

    def InstanceFun(self):
        print("InstanceFun");
        print(self);

    @classmethod
    def ClassFun(cls):
        print("ClassFun");
        print(cls);

    @staticmethod
    def StaticFun():
        print("StaticFun");

    #这个函数算鸟东西?
    def Ballshurt():
        print("Ballshurt");


t = Test();
t.InstanceFun();
Test.ClassFun();
#t.Ballshurt(); #access error
Test.Ballshurt();
Test.StaticFun();
t.StaticFun();
t.ClassFun();
Test.InstanceFun(t);
Test.InstanceFun(Test);



在C++中类方法其实就是静态方法因为逻辑上没任何区别,实现上静态方法中同样可以直接访问类本身,
所以依鄙人愚见python纯属多此一举,OO术语这下搞的更乱了。
[解决办法]
其实, @classmethod 还是很有用的, 通过他, 可以对class做动太的匹配, 下面就是刚想到的场景 , 因为@staticmethod没有把cls 传进去, 就不行. @staticmethod 仅仅是逻辑上和class 帮在一起

cls 这个参数在metaclass 里到处可见



class Color(object):
    _color = (0, 0, 0);

    @classmethod
    def value(cls):
        if cls.__name__== 'Red':
            cls._color  = (255, 0, 0)

        elif cls.__name__ == 'Green':
            cls._color = (0, 255, 0)

        return cls._color

class Red(Color):
    pass

class Green(Color):
    pass

class UnknownColor(Color):
    pass

red = Red()
green = Green()
xcolor = UnknownColor()



print 'red = ', red.value()
print 'green = ', green.value()
print 'xcolor =', xcolor.value()



#--------- 输出 -----------
#red =  (255, 0, 0)
#green =  (0, 255, 0)
#xcolor = (0, 0, 0)
#
[解决办法]
引用:
其实, @classmethod 还是很有用的, 通过他, 可以对class做动太的匹配, 下面就是刚想到的场景 , 因为@staticmethod没有把cls 传进去, 就不行. @staticmethod 仅仅是逻辑上和class 帮在一起

cls 这个参数在metaclass 里到处可见


Python code


class Color(object):
    _……

你说的倒是一种应用,不过基类任务是抽象共性,假设应用所有颜色那么Color要判断16581375种么?
如果我只应用其中1种,16581375 - 1全是浪费。这里设置颜色应该是子类的责任,基类只是提供一个
标准接口。

class Color(object):
#    _color = "Color"; 不加是虚基类
    def Value(self):
        return self._color;

class Red(Color):
    _color = "Red";
class Green(Color):
    _color = "Green";

r = Red();
g = Green();
print(r.Value());
print(g.Value());




[解决办法]
引用:
觉的一方面加强所谓类的封装性,避免A.Foo1();A.Foo2();这种暴力的全名调用方式,另一方面函数的意图也比较明显,代码容易阅读。现在@装饰语法也有了,修改函数可不碰触原函数内部,在新地方写个装饰函数补强之...

不太明白你说的暴力在哪,不过这代码用@classmethod更好,如此类也可以调用了逻辑上更自然。

class Color(object):
    @classmethod
    def Value(cls):
        return cls._color;


不过@staticmethod情何以堪。。。反正都一个意思我是认为没必要同时存在,
而且可读性C++加个static已经很好了嘛。

热点排行