python3 开发之一:classmethod和staticmethod

1.staticmethod

对于一般的计算机语言,都会提供静态方法,这个方法可以认为是类的方法。即可以直接 类.方法(),也可以通过类的实例,也就是对象.方法()进行调用。就静态方法这方面来说,python语言和其他提供了静态方法的语言来说并没什么区别。

比如在java中,main方法(主函数)就是一个静态方法。

class Test
{
    public static void main(String[] args)
    {
        //code
    }
}

而在python中则采用装饰器的形式(python中并没有主函数的概念),即@staticmethod

class Test(object):
    @staicmethod
    def main():
        pass

以上两者虽然在形式上有所不同,但是在使用上是一样的。

扩展阅读:装饰器

2.classmethod

从字面上来看,classmethod的意思是类方法,看起来和staticmethod类似,但其实不然,不过它们还是有相似之处的。

相似之处

  1. classmethod和staticmethod修饰符对应的函数不需要实例化,即不需要self参数。
  2. 可以调用的属性和方法。

除了上面提到的之外,它们两个的用法则是南辕北辙。比如,classmethod的第一个参数cls来表示类(默认情况)。


接下来,以一个具体的场景来说明。

假设要使用python3自己开发一个ORM(Object Relate Mapping,对象关系映射)。

数据库中有一个user表, 主键是uid,其他的还有name 名字、password 密码。那么在程序中使用时就需要查表来获取对应的数据,并把一列数据封装成一个对象。也就是说,程序需要一个从数据库的数据到python对象的映射,这个映射就叫做ORM。

本篇不打算具体讲解是如何映射的,想要具体了解的可以点这里

假设你已经把基础的工作都做好了,那么此时的UML图如下所示:

 即Model继承自dict,并提供了一些通用的函数。比如find()方法,就是根据主键查表获取满足条件的数据。

对于python来说,这个方法是可以放在Model中的,那就是使用到classmethod装饰器:

class Model(dict, metaclass=ModelMetaclass):
    #...
    @classmethod
    def find(cls, pk):
        """find object by primary key"""
        sql = '%s where `%s`=?' % (cls.__select__, cls.__primary_key__)
        rs = db.select_one(sql, pk)

        if rs is None:
            return None
        return cls(**rs)

上面的代码比较简单,功能就是根据主键来进行查表,如果找到对应的数据项(db.select_one返回的是dict或者None),则调用cls的构造方法来创建cls类的一个实例。

如果不使用classmethod而是使用staticmethod的话,就只能把上面的方法稍微修改后放到User当中。

class User(Model):
    #...
    @staticmethod
    def find(pk):
        """find object by primary key"""
        sql = '%s where `%s`=?' % (User.__select__, User.__primary_key__)
        rs = db.select_one(sql, pk)

        if rs is None:
            return None
        return User(**rs)

综合比较上面的代码就可以发现,两者的代码基本一致,只不过由通用的cls转到了具体的User而已。

换句话说,在python3中,类本身也可以作为一个变量来传递。

`@classmethod` `@staticmethod` 是 Python 中用来定义类方法静态方法的装饰器。 `@classmethod` 装饰器用于定义类方法。类方法是绑定到类而不是实例的方法,可以通过类或实例调用。类方法的第一个参数通常被约定为 `cls`,表示类本身,而不是实例。类方法可以访问类的属性调用其他类方法。 示例: ```python class MyClass: @classmethod def my_class_method(cls, arg1, arg2): # 类方法可以访问类的属性 print(cls.__name__) print(arg1, arg2) # 通过类调用类方法 MyClass.my_class_method('hello', 'world') # 输出: # MyClass # hello world # 也可以通过实例调用类方法 obj = MyClass() obj.my_class_method('hello', 'world') # 输出: # MyClass # hello world ``` `@staticmethod` 装饰器用于定义静态方法。静态方法不需要访问实例或类的状态,因此不需要传递 `self` 或 `cls` 参数。静态方法可以通过类或实例直接调用。 示例: ```python class MyClass: @staticmethod def my_static_method(arg1, arg2): print(arg1, arg2) # 通过类调用静态方法 MyClass.my_static_method('hello', 'world') # 输出: # hello world # 也可以通过实例调用静态方法 obj = MyClass() obj.my_static_method('hello', 'world') # 输出: # hello world ``` 总结: - `@classmethod` 用于定义类方法,第一个参数为类本身,可以访问类的属性调用其他类方法。 - `@staticmethod` 用于定义静态方法,不需要访问实例或类的状态,可以通过类或实例直接调用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值