没有自我的内部阶级功能

时间:2017-11-01 11:50:54

标签: python python-3.x class

和平,大家好! 我使用的是Python 3.6.3,我觉得奇怪的是这样的构造是可能的:

class TestClass(object):
    def __init__(self):
        self.arg = "arg"

    def test():
        print("Hey test")

使用:

>>> TestClass.test()
"Hey test"

我知道在Python中有标准方法self作为参数(不知道如何正确调用它们),静态方法,类方法,抽象方法。

但是test()是什么样的方法? 这是静态方法吗?

编辑:

在类中确定函数的方法是否有任何有用的用法?

5 个答案:

答案 0 :(得分:4)

让我用一个例子来解释:

class TestClass(object):
  def __init__(self):
    self.arg = "arg"

  def test1():
    print("class method test1, Hey test")

  @classmethod
  def test2(cls):
    print("class method test2, Hey test")

  def test3(self):
    print("instance method test3, Hey test")

查看使用类或实例调用test1时会发生什么:

<强>首先

  TestClass.test1() #called from class
class method test1, Hey test
   TestClass().test1() #created an instance TestClass()
Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: test1() takes 0 positional arguments but 1 was given

这是因为当你创建一个实例时,会使用self参数,但是在这里,该方法没有自我参数,这就是它制动的原因。

下一个!

   TestClass.test2()
class method test2, Hey test
   TestClass().test2()
class method test2, Hey test

例如,为了课堂,为什么?好吧,正如你可以看到test2(cls)接受一个论证,cls,在这里,我没有使用它,所以它确实有效。

带给我下一个主题,muajaja

  TestClass().test3()
instance method test3, Hey test
   TestClass.test3()
Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: test3() missing 1 required positional argument: 'self'

很容易看到,当你把它称为课堂时,你还没有提供自我参数

答案 1 :(得分:3)

在Python 3中,(与Python 2不同)从类中访问和调用的函数只是另一个函数;没什么特别的:

  

请注意,从函数对象到实例方法的转换   每次从实例中检索属性时都会发生对象。

[强调我的]

您恰好使用正确的参数集调用函数,尽管通过类对象访问。与通过实例调用方法的基础函数对象相同:

TestClass().test.__func__() # "Hey test"

快速测试进一步解释:

print(TestClass().test is TestClass.test)
# False
print(TestClass().test.__func__ is TestClass.test)
# True

但是,在Python 2中,行为是不同的,因为当通过类或实例访问属性时,会发生从函数对象到方法对象的转换:

  

请注意转换从函数对象到(unbound或   每次从中检索属性时都会发生方法对象   班级或实例。

[强调我的]

答案 2 :(得分:3)

在python 3中,函数和类中定义的函数没有区别:

def test():
    print("Hey test")

class TestClass:
    def test():
        print("Hey test")

test() # works
TestClass.test() # also works

这两个都是正常的功能。

当您通过类的实例访问函数时,会发生隐式self参数的魔力,如下所示:

obj = TestClass()
obj.test() # throws an error because the test function doesn't accept arguments

这是函数 test变为(绑定)方法 test的时候。如果打印它们,您可以看到区别:

print(TestClass.test) 
print(instance.test)
# output:
# <function TestClass.test at 0xaaaaaa>
# <bound method TestClass.test of <__main__.TestClass object at 0xbbbbbb>>

总结一下:

  • 通过课程访问功能可以为您提供原始功能。
  • 通过实例访问函数会为您提供一个带有绑定self参数的方法。

有关从函数到绑定方法的转换方式的详细信息,请参阅the descriptor how-to,特别是the section about functions

答案 3 :(得分:1)

Python 3省略了Python 2中存在的绑定和非绑定方法之间的区别。之前的未绑定方法现在只是一个常规函数。

var arr = [    "data": {
      "plmn": "",
      "id": "",
      "time": '',
      "cell": {
        "rsrp": [
          0,
          1,
          2
        ],
        "rsrq": [
          0,
          1,
          2
        ],
        "earfcn": '',
        "pci": '',
        "celltiming": [
          0,
          1
        ],
        "sinr": [
          0,
          1
        ]
      },
      "mac": ""
    },
    "time": '',
    "deviceID": ""]

在Python 2中:

class A(object):
    def test():
        pass

而在Python 3中:

>>> A.test
<unbound method A.test>

(地址可能不同)

>>> A.test <function A.test at 0x101cbbae8> 这是一个描述符;当你访问test时,你不必(必然)取回原始的功能对象;相反,你得到该对象的返回值(即函数的)A.test方法,该方法用两个参数调用。哪些参数取决于您是通过类还是通过类的实例访问它。

  • __get__ =&gt; A.test
  • A.test.__get__(None, A) =&gt; a = A(); a.test

在Python 2中,A.test.__get__(a, A)返回一个A.test.__get__(None, A)对象,它是原始函数的包装器。作为未绑定 method,包装器仍然期望method的实例作为其第一个参数,即使函数本身未使用任何参数定义。

但是,在Python 3中,A只返回对原始函数的引用,不是一个A.test.__get(None, A)对象。因此,您可以完全按照您在第一时间的定义使用它。

您可以通过检查Python 2和Python 3中的methodid(A.__dict__['test'])来确认这一点。在Python 2中,您将获得两个不同的值;在Python 3中,您将获得相同的值。

答案 4 :(得分:0)

TestClass.test()调用实际上会执行对象上的test()。这类似于@staticmethod(可以在类对象上执行的方法,而不首先创建对象)。

ins = TestClass()
ins.test()

将抛出异常,因为实例方法 self 作为第一个参数传递,而test()不带args。

创建对象时,clas中定义的方法绑定。它们实际上是不同的对象,因此它们具有不同的ID:

   id(TestClass.test)
=> 140288592901800
   obj = TestClass()
   id(obj.test)
=> 140288605765960

在Python 2.7中,您的代码抛出一个异常的自我解释:

Traceback (most recent call last):
  File "<pyshell#404>", line 1, in <module>
    TestClass.test()
TypeError: unbound method test() must be called with TestClass instance as 
first argument (got nothing instead)