python-静态方法staticmethod类方法classmethod属性方法property

Posted konglingbin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python-静态方法staticmethod类方法classmethod属性方法property相关的知识,希望对你有一定的参考价值。

 Python的方法主要有3个,即静态方法(staticmethod),类方法(classmethod)和实例方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def foo(x):
    print "executing foo(%s)"%(x)
  
class A(object):
    def foo(self,x):
        print "executing foo(%s,%s)"%(self,x)
  
    @classmethod
    def class_foo(cls,x):
        print "executing class_foo(%s,%s)"%(cls,x)
  
    @staticmethod
    def static_foo(x):
        print "executing static_foo(%s)"%x
  
a=A()

这个self和cls是对类或者实例的绑定,对于一般的函数来说我们可以这么调用foo(x),这个函数就是最常用的,它的工作跟任何东西(类,实例)无关.对于实例方法,我们知道在类里每次定义方法的时候都需要绑定这个实例,就是foo(self, x),为什么要这么做呢?因为实例方法的调用离不开实例,我们需要把实例自己传给函数,调用的时候是这样的a.foo(x)(其实是foo(a, x)).类方法一样,只不过它传递的是类而不是实例,A.class_foo(x).注意这里的self和cls可以替换别的参数,但是python的约定是这俩,还是不要改的好.

对于静态方法其实和普通的方法一样,不需要对谁进行绑定,唯一的区别是调用的时候需要使用a.static_foo(x)或者A.static_foo(x)来调用.

 

\\实例方法类方法静态方法
a = A() a.foo(x) a.class_foo(x) a.static_foo(x)
A 不可用 A.class_foo(x) A.static_foo(x)

 

类的普通方法

class Animal(object):
    def __init__(self,name):
        self.name = name
    def intro(self):
        print(\'there is a %s\'%(self.name))
cat = Animal(\'cat\')
cat.intro()
  • 静态类方法
class Animal(object):
    def __init__(self,name):
        self.name = name
    @staticmethod
    def intro(self):
        print(\'there is a %s\'%(self.name))
cat = Animal(\'cat\')
cat.intro()
  • 加上装饰器后运行会报错,原因是方法变为一个普通函数,脱离的与类的关系,不能引用构造函数中的变量了。 

使用场景举例:python内置方法os中的方法,可以直接使用的工具包,跟类没关系。


class Animal(object):
    def __init__(self,name):
        self.name = name
    @classmethod
    def intro(self):
        print(\'there is a %s\'%(self.name))
cat = Animal(\'cat\')
cat.intro()
  • 报错信息 

如果换成

class Animal(object):
    name = \'cat\'
    def __init__(self,name):
        self.name = name
    @classmethod
    def intro(self):
        print(\'there is a %s\'%(self.name))
cat = Animal(\'cat\')
cat.intro()
  • 可以正常运行。 

结论:类方法只能调用类变量,不能调用实例变量


属性方法@property 把一个方法变为(伪装成)类属性。因为类属性的实质是一个类变量,用户可以调用变量就可以修改变量。某些特定场景要限制用户行为,就用到静态方法。 
@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。(摘自廖雪峰的博客)

class Animal(object):
    def __init__(self,name):
        self.name = name
    @property
    def intro(self,food):
        print(\'there is a %s eating %s\'%(self.name,food))
cat = Animal(\'cat\')
cat.intro()
  • 报错:

     

  • 方法不能正常调用。如果要调用,如下:
cat.intro
  • 是这样的话,方法就没办法单独传入参数。如果要传入参数,如下:
class Animal(object):
    def __init__(self,name):
        self.name = name
    @property
    def intro(self):
        print(\'there is a %s eating %s\'%(self.name,food))
    @intro.setter
    def intro(self,food):
        pass
cat = Animal(\'cat\')
cat.intro
  • cat.intro还有其他操作getter deleter等等。

一:staticmethod

代码如下:
class Singleton(object):
    instance = None

    def __init__(self):
        raise SyntaxError(\'can not instance, please use get_instance\')

    @staticmethod
    def get_instance():
        if Singleton.instance is None:
            Singleton.instance = object.__new__(Singleton)
        return Singleton.instance

a = Singleton.get_instance()
b = Singleton.get_instance()
print(\'a id=\', id(a))
print(\'b id=\', id(b))
该方法的要点是在__init__抛出异常,禁止通过类来实例化,只能通过静态get_instance函数来获取实例;因为不能通过类来实例化,所以静态get_instance函数中可以通过父类object.__new__来实例化。
 

二:classmethod

和方法一类似,代码:
 
class Singleton(object):
    instance = None

    def __init__(self):
        raise SyntaxError(\'can not instance, please use get_instance\')

    @classmethod
    def get_instance(cls):
        if Singleton.instance is None:
            Singleton.instance = object.__new__(Singleton)
        return Singleton.instance

a = Singleton.get_instance()
b = Singleton.get_instance()
print(\'a id=\', id(a))
print(\'b id=\', id(b))
该方法的要点是在__init__抛出异常,禁止通过类来实例化,只能通过静态get_instance函数来获取实例;因为不能通过类来实例化,所以静态get_instance函数中可以通过父类object.__new__来实例化。
 

三:类属性方法

和方法一类似, 代码:
class Singleton(object):
    instance = None

    def __init__(self):
        raise SyntaxError(\'can not instance, please use get_instance\')

    def get_instance():
        if Singleton.instance is None:
            Singleton.instance = object.__new__(Singleton)
        return Singleton.instance

a = Singleton.get_instance()
b = Singleton.get_instance()
print(id(a))
print(id(b))
该方法的要点是在__init__抛出异常,禁止通过类来实例化,只能通过静态get_instance函数来获取实例;因为不能通过类来实例化,所以静态get_instance函数中可以通过父类object.__new__来实例化。
 

四:__new__

常见的方法, 代码如下:

 

class Singleton(object):
    instance = None

    def __new__(cls, *args, **kw):
        if not cls.instance:
            # cls.instance = object.__new__(cls, *args)
            cls.instance = super(Singleton, cls).__new__(cls, *args, **kw)
        return cls.instance


a = Singleton()
b = Singleton()
print(id(a))
print(id(b))

 

 

五:装饰器

代码如下:

 

def Singleton(cls):
    instances = {}

    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance


@Singleton
class MyClass:
    pass

a = MyClass()
b = MyClass()
c = MyClass()

print(id(a))
print(id(b))
print(id(c))

 

 

六:元类

python2版:
class Singleton(type):
    def __init__(cls, name, bases, dct):
        super(Singleton, cls).__init__(name, bases, dct)
        cls.instance = None

    def __call__(cls, *args):
        if cls.instance is None:
            cls.instance = super(Singleton, cls).__call__(*args)
        return cls.instance


class MyClass(object):
    __metaclass__ = Singleton


a = MyClass()
b = MyClass()
c = MyClass()
print(id(a))
print(id(b))
print(id(c))
print(a is b)
print(a is c)

或者:
class Singleton(type):
    def __new__(cls, name, bases, attrs):
        attrs["_instance"] = None
        return super(Singleton, cls).__new__(cls, name, bases, attrs)

    def __call__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instance


class Foo(object):
    __metaclass__ = Singleton

x = Foo()
y = Foo()
print(id(x))
print(id(y))
 
python3版:
class Singleton(type):
    def __new__(cls, name, bases, attrs):
        attrs[\'instance\'] = None
        return super(Singleton, cls).__new__(cls, name, bases, attrs)

    def __call__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
        return cls.instance


class Foo(metaclass=Singleton):
    pass

x = Foo()
y = Foo()
print(id(x))
print(id(y))
 

七:名字覆盖

代码如下:
class Singleton(object):
    def foo(self):
        print(\'foo\')

    def __call__(self):
        return self


Singleton = Singleton()

Singleton.foo()

a = Singleton()
b = Singleton()
print(id(a))
print(id(b))

 

以上是关于python-静态方法staticmethod类方法classmethod属性方法property的主要内容,如果未能解决你的问题,请参考以下文章

python-静态方法staticmethod类方法classmethod属性方法property

开发者笔记python中的类方法(@classmethod)和静态方法(@staticmethod)

Python面向对象 | 静态方法 staticmethod

面试必问python实例方法类方法@classmethod静态方法@staticmethod和属性方法@property区别

python中静态方法(@staticmethod)和类方法(@classmethod)的区别

Python进阶-----静态方法(@staticmethod)