社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python:将类方法分配给变量

JustUsNow • 3 年前 • 1191 次点击  

我在一个类中有很多方法,我需要调用一个特定的方法。我试过这样的方法,但却发现了一个属性错误

class MyClass:
    def first(a, b):
        return a + b
    def second(a, b):
        return a * b

a = 2
b = 3

first_func = MyClass.first
second_func = MyClass.second

my_obj = MyClass()

我希望下面的东西能起作用,但我有个例外:

my_obj.first_func(a, b) + my_obj.second_func(a, b) == 11

有没有办法做到这一点?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/132045
 
1191 次点击  
文章 [ 3 ]  |  最新文章 3 年前
SorousH Bakhtiary
Reply   •   1 楼
SorousH Bakhtiary    3 年前

有几件事我们应该在这里讨论。我将试着解释不同的场景,给你们一个概览,看看发生了什么。

首先让我们看看你的最后一行:

my_obj.first_func(a, b) + my_obj.second_func(a, b)

你是想得到 first_func 来自实例的属性 my_obj .它(或它的班级)有吗?
第一_func 是全局模块中的一个变量。 我的obj 对此一无所知。

所以你的例外是因为这个。。。


现在考虑一下你的方法:
first second 方法是类中的常规方法。当你说 MyClass.first ,您将获得一个函数对象 不是一种方法 .此函数接受两个参数 a b .

但是如果你说 my_obj.first_func 你得到一个 方法对象 它有一个绑定实例对象。Python用对调用此方法的实例的引用来填充第一个参数。现在,您的方法对象只接受一个参数 B (这就是描述符的工作原理)

话虽如此,你在这里有一些选择:

1-仅从类而不是实例调用它们:

否则会出现异常,因为Python已经用实例对象填充了第一个参数。

class MyClass:
    def first(a, b):
        return a + b

    def second(a, b):
        return a * b

first_func = MyClass.first
second_func = MyClass.second
print(first_func(2, 3) + first_func(2, 3))

2.用绿色装饰 staticmethod :

现在可以从实例或类调用,Python不会为您填充第一个参数。

class MyClass:
    @staticmethod
    def first(a, b):
        return a + b

    @staticmethod
    def second(a, b):
        return a * b

first_func = MyClass.first
second_func = MyClass.second
print(first_func(2, 3) + first_func(2, 3))
class MyClass:
    @staticmethod
    def first(a, b):
        return a + b

    @staticmethod
    def second(a, b):
        return a * b

my_obj = MyClass()
first_func = my_obj.first
second_func = my_obj.second
print(first_func(2, 3) + first_func(2, 3))

3-添加一个 self 参数(其名称不是规则,而是强烈建议的约定):

这一次,如果从实例调用它们,则不需要将实例传递给第一个参数,但如果从类调用它们,则需要将其作为第一个参数传递。

class MyClass:
    def first(self, a, b):
        return a + b

    def second(self, a, b):
        return a * b


my_obj = MyClass()
first_func = my_obj.first
second_func = my_obj.second
print(first_func(2, 3) + first_func(2, 3))
class MyClass:
    def first(self, a, b):
        return a + b

    def second(self, a, b):
        return a * b


my_obj = MyClass()
first_func = MyClass.first
second_func = MyClass.second
print(first_func(my_obj, 2, 3) + first_func(my_obj, 2, 3))
Akash garg
Reply   •   2 楼
Akash garg    3 年前

类中的函数定义应包含“self”作为参数

class MyClass:
    def first(self,a, b):
        return a + b
    def second(self,a, b):
        return a * b

a = 2
b = 3

first_func = MyClass.first
second_func = MyClass.second

my_obj = MyClass()
first_func(my_obj,a, b) + second_func(my_obj,a, b) == 11
stellasia
Reply   •   3 楼
stellasia    3 年前

因为你的方法没有 self 参数,它们是“静态”的,不依赖于指定的对象。可以这样调用函数:

first_func(a, b)  # no my_obj

如果事实上它们确实依赖于对象,你会写道:

class MyClass:
    def first(self, a, b):
        return a + b
    def second(self, a, b):
        return a * b

你可以在对象上调用方法:

my_obj = MyClass()
my_obj.first(a, b)

或者,用你的初始符号:

first_func = MyClass.first
first_func(my_obj, a, b)

(你的朋友也一样 second (方法)