Python 如何在类内调用没有参数的函数?想要没有装饰的解决方案吗

Python 如何在类内调用没有参数的函数?想要没有装饰的解决方案吗,python,Python,如何在类内调用没有参数的函数?我已经知道@staticmethod和@classmethod了。这个问题所问的是没有@staticmethod的解决方案 这是我在学习@staticmethod和@classmethod之后提出的一个问题。我很好奇,如果这样的函数没有任何参数和装饰符,它是否会变成一个永远无法调用的函数 详细说明 我已经知道那些方法是行不通的。但我只是向你展示结果 >>> a = RRR() >>> a.x() Traceback (most r

如何在类内调用没有参数的函数?我已经知道@staticmethod和@classmethod了。这个问题所问的是没有@staticmethod的解决方案

这是我在学习@staticmethod和@classmethod之后提出的一个问题。我很好奇,如果这样的函数没有任何参数和装饰符,它是否会变成一个永远无法调用的函数

详细说明 我已经知道那些方法是行不通的。但我只是向你展示结果

>>> a = RRR()
>>> a.x()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in x
NameError: global name 'ss' is not defined
>>> a.y()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in y
TypeError: ss() takes no arguments (1 given)
>>> a.z()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in z
TypeError: unbound method ss() must be called with RRR instance as first argument (got nothing instead)
我想知道如何调用像RRR.ss这样的函数?有没有其他可能的方法来调用这样的函数

我已经知道,只需在ss函数之前添加一行@staticmethod,就可以像self.ss或RRR.ss一样调用该函数


但在这个问题中,我想问的是,没有添加@staticmethod,并且保持RRR.ss的声明代码不变,有没有办法调用RRR.ss?或者该函数是一个永远无法调用的函数

我没有解决任何现实问题。我只是好奇这类函数的状态。通过这样的声明,我是否创建了一个无用的函数,一个无法通过任何方式访问的函数?这只是一个理论问题

谢谢

我已经知道了,只需在前面添加一行@staticmethod ss函数,则该函数可以像self.ss或
RRR.ss。但在这个问题上,我想问的是,保持 RRR.ss声明代码不变,有没有办法调用RRR.ss? 或者该函数是一个永远无法调用的函数

这并不是说它永远无法被调用,只是它不在范围之内。一个类定义了一个名称空间,把它想象成一堵带门的墙,而该类主体内的所有内容都在墙的后面。要访问或调用它,您需要通过门,门是类的实例或类本身

这称为解析,即找出名称的定义位置,以便使用它。默认情况下,当您运行它在特定范围内运行的任何代码时;要了解作用域中的可用内容,您可以使用全局作用域和局部作用域的全局作用域和局部作用域:

Python 2.7.3 (default, Jan  2 2013, 16:53:07)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}
>>> locals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}
如您所见,当您第一次启动Python交互式提示符时,它的作用域中有一些内容。现在,当您创建一个类时,会发生以下情况:

>>> class Foo(object):
...     def a():
...        print 'Hello'
...
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'Foo': <class '__main__.Foo'>, '__doc__': None, '__package__': None}
>>> locals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'Foo': <class '__main__.Foo'>, '__doc__': None, '__package__': None}

您注意到只有Foo可用,而不是a。为了让我获得a,我必须通过使用Foo限定它来指定它的范围。这个是范围解析运算符。

代码中的ss不是一个很好的方法;它是放置在类中的可调用函数。在查找方法时,Python将该方法绑定到实例,注入第一个参数,该参数保证是正确的类装饰器(如classmethod和staticmethod)的实例来处理该参数。这就是a.x的情况;它是一个可通过实例属性调用的类,因此生成绑定方法。由于ss不接受此参数,因此无法使用方法调用它。但是,可以从类中调用它,例如,使用..uuu class.uuu dict_uuu['ss']或a.ss.im_func调用,这是前面提到的展开Martijn Pieters

这个例子应该让事情变得更清楚一些:

class Dog(object):

    def __init__(self, name):
        self.name = name

    def get_name(self):
        """
        Instance method
        Gets passed the instance as the implicit first argument
        """
        print "My name is '{}'".format(self.name)

    @classmethod
    def get_class(cls):
        """
        Class method
        Gets passed the class as the implicit first argument
        """
        print "I'm the '{}' class".format(cls.__name__)

    @staticmethod
    def foo():
        """
        Static method
        Gets passed *no* implicit arguments. Basically just a
        function attached to a class.
        """
        print "I've got no arguments"


dog = Dog('spot')

dog.get_name()
Dog.get_class()
Dog.foo()
输出:

My name is 'spot'
I'm the 'Dog' class
I've got no arguments
您可以在实例dog.foo或self.foo上调用静态或类方法,但通常不应该这样做,因为您混淆了这样一个事实,即它们没有将实例作为参数


有关更多详细信息,请参阅和decorators上的文档。

为什么需要使ss完全不带参数可调用?你想解决什么问题?但在这个问题上,我想问的是,保持RRR.ss的声明代码不变,有没有办法调用RRR.ss?“你看不见这一段吗?”詹尼亚昌:是的,这个问题还不清楚。为什么OP想要这样?他们在这里的目标是什么?了解如何创建方法对象以及如何再次展开它们?在这种情况下,这是一个重复的例子。@MartijnPieters是的,你说到点子上了。我不是在解决问题。我只是好奇函数类型的条件。通过这样的声明,我是否创建了一个任何方法都无法访问的函数?您创建了一个无法遵守方法预期约定的函数。这主要意味着您不了解方法是如何工作的,以及它们为什么有这些约定。您仍然可以绕过方法创建或打开创建的方法并调用基础函数。嗯,这不是一个范围问题,除了在RRR.x中尝试调用之外,我假设OP只是在绝望中尝试的,因为调用方法的其他方法不起作用。为了让我得到一个,我必须用Foo限定它的范围。但是Foo.a仍然不起作用。1 a.“类”不起作用2 a.“类”和RRR.s有什么不同? 据我所知,它们是一样的。我已经知道@classmethod和@staticmethod。在这个问题上,我想知道的是,一个没有任何装饰函数和参数的方法是如何被调用的。没有一些黑魔法是不容易的。它将是一个常规的实例方法,需要绑定到一个实例隐式实例参数,或者显式地传递一个实例作为第一个参数——如果它不接受任何参数,那么它将使用violoate签名。
My name is 'spot'
I'm the 'Dog' class
I've got no arguments