class TestClass(object):
def __init__(self):
self.arg = "arg"
def test():
print("Hey test")
使用:
>>> TestClass.test()
"Hey test"
我知道在Python中有标准方法self
作为参数(不知道如何正确调用它们),静态方法,类方法,抽象方法。
但是test()
是什么样的方法?
这是静态方法吗?
编辑:
在类中确定函数的方法是否有任何有用的用法?
答案 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中的method
和id(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)