一个类方法,当作为实例方法调用时,行为不同? [英] A class method which behaves differently when called as an instance method?

查看:211
本文介绍了一个类方法,当作为实例方法调用时,行为不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有可能使一个方法在作为类方法调用时比作为实例方法调用时有所不同。

I'm wondering if it's possible to make a method which behaves differently when called as a class method than when called as an instance method.

例如,一个技能改进项目,我写一个 Matrix 类(是的,我知道有完美的矩阵类已经有)。我创建了一个名为 identity 的类方法,它返回指定大小的单位矩阵。

For example, as a skills-improvement project, I'm writing a Matrix class (yes, I know there are perfectly good matrix classes already out there). I've created a class method for it called identity which returns an identity matrix of a specified size.

,当在 Matrix 实例上调用时,似乎不需要指定大小,它应该返回一个与 Matrix 相同大小的单位矩阵。

Now, when called on an instance of Matrix, it seems logical that the size shouldn't need to be specified; it should return an identity matrix of the same size as the Matrix it's called on.

换句话说,I喜欢定义一个方法,可以确定它是否通过实例调用,如果是,访问该实例的属性。不幸的是,即使通过文档和几个Google搜索,我还没有找到任何建议这是可能的。有谁知道不同?

In other words, I'd like to define a method which can determine whether it was called via an instance and, if so, access that instance's attributes. Unfortunately, even after digging through the documentation and a few Google searches, I haven't found anything which suggests this is possible. Does anyone know differently?

编辑

显然,我还是不习惯一流的函数。

Wow! Clearly, I'm still not quite used to first-class functions. Here's what I ended up with — thanks to Unknown for providing the key!

class Foo(object):
    def __init__(self, bar):
        self.baz = bar
        self.bar = MethodType(lambda self: self.__class__.bar(self.baz), self, self.__class__)

    @classmethod
    def bar(cls, baz):
        return 5 * baz

Foo.bar(3) # returns 15

foo = Foo(7)
foo.bar() # returns 35

Edit 2:

只是一个快速注释 - 这种技术(和下面的大多数)不能用于定义<$ c $

Just a quick note — this technique (and most of those presented below) won't work on classes which define __slots__, as you cannot reassign the method.

推荐答案

有问题的Python黑客是我的forte 。

Questionably useful Python hacks are my forte.

from types import *

class Foo(object):
    def __init__(self):
        self.bar = methodize(bar, self)
        self.baz = 999

    @classmethod
    def bar(cls, baz):
        return 2 * baz


def methodize(func, instance):
    return MethodType(func, instance, instance.__class__)

def bar(self):
    return 4*self.baz


>>> Foo.bar(5)
10
>>> a=Foo()
>>> a.bar()
3996

这篇关于一个类方法,当作为实例方法调用时,行为不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆