class Person():
pass;
def say_hi(self):
print 'hii'
me=Person()
me.say_hi=say_hi
me.say_hi()
Isn't the self argument automatically passed in python ? why why is calling me.say_hi()
is giving a stack trace ?
self参数不是在python中自动传递的吗?为什么调用me.say_hi()会给出堆栈跟踪?
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: say_hi() takes exactly 1 argument (0 given)
8 个解决方案
#1
6
(This can act as some demonstration for aaronasterling's answer.)
(这可以为aaronasterling的回答提供一些示范。)
Here are the definitions:
这是定义:
>>> class Person(object):
... def bound(self):
... print "Hi, I'm bound."
...
>>> def unbound(self):
... print "Hi, I'm unbound."
...
Note the types of these methods and functions.
注意这些方法和函数的类型。
>>> type(Person.bound)
<type 'instancemethod'>
>>> type(Person().bound)
<type 'instancemethod'>
>>> type(unbound)
<type 'function'>
>>> Person.unbound = unbound
When it gets set on the Person
before instantiation, it gets bound.
在实例化之前,当它在Person上设置时,它就被绑定。
>>> Person().bound()
Hi, I'm bound.
>>> Person().unbound()
Hi, I'm unbound.
However, if it's set after instantiation, it's still of type 'function'.
但是,如果在实例化之后设置它,它仍然是“function”类型。
>>> me = Person()
>>> me.rebound = unbound
>>> type(me.rebound)
<type 'function'>
>>> type(me.unbound)
<type 'instancemethod'>
>>> me.rebound
<function unbound at 0x7fa05efac9b0>
>>> me.rebound()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound() takes exactly 1 argument (0 given)
The 'instancemethod' type can be used to bind a 'function' to an object. It's in the types
module as MethodType
.
“instancemethod”类型可用于将“function”绑定到对象。它在types模块中作为MethodType。
>>> import types
>>> me.rebound = types.MethodType(unbound, me, Person)
Now it's bound properly.
现在是正确。
>>> type(me.rebound)
<type 'instancemethod'>
>>> me.rebound()
Hi, I'm unbound.
>>> # Not true any more!
#2
12
It's not passed in the way that you are doing it.
这不是你做这件事的方式。
You would have to do.
你必须这么做。
import types
me.say_hi = types.MethodType(say_hi, me, Person)
for it to work.
为它工作。
When python instantiates a class, it essentially carries out the above procedure for each of the class methods. When you 'monkey-patch' a method onto an object in the way that you were trying to do it, it's not a bound method and just exists as a function in instance.__dict__
. Calling it is no different than calling any other function. If you want to stick a method on an instance, you have to manually make it a method as shown above.
当python实例化一个类时,它实质上是为每个类方法执行上述过程。当你在一个对象上“monkey-patch”一个方法时,它并不是一个绑定方法,而是作为一个函数存在于instance.__dict__中。调用它与调用任何其他函数没有区别。如果您想在一个实例上粘贴一个方法,您必须手动地将其作为一个方法,如上面所示。
If you were to do
如果你要这么做的话
class Person(object):
pass
def say_hi(self):
print 'hii'
Person.say_hi = say_hi
me = Person()
me.say_hi()
then it would work because Python will create the method for you.
然后它会工作,因为Python会为您创建方法。
Chris Morgan put up an answer that shows this one in action. It's good stuff.
克里斯·摩根给出的答案显示了这一点。这是好东西。
#3
3
In this case say_hi is not method of your class. It is just reference to a function. This is why the self argument is not passed automatically.
在这种情况下,say_hi不是类的方法。它只是一个函数的引用。这就是为什么self参数不会自动传递。
Or just use:
或者只是使用:
class Person():
def say_hi(self):
print 'hii'
me=Person() me.say_hi=say_hi me.say_hi()
#4
1
The self argument of a method is passed automatically. You don't have a method, but a function that is an attribute of an object. If you did Person.say_hi = say_hi
, then Person().say_hi() would work as expected. A method is a function that's attribute of a class, not an instance, and self is passed only for methods.
方法的self参数将自动传递。你没有一个方法,但是一个函数是一个对象的属性。如果你的人。say_hi = say_hi,然后Person().say_hi()会像预期的那样工作。方法是类的属性,而不是实例,而self仅用于方法。
Class attributes define how the instances should work, while instance attributes are just normal you access. This means that class attributes are modified when they are accessed from an instance (e.g. functions are turned into methods), while instance attributes are left unchanged.
类属性定义实例应该如何工作,而实例属性只是您访问的普通属性。这意味着类属性在从实例访问时被修改(例如,函数被转换为方法),而实例属性则保持不变。
>>> class A(object): pass
...
>>> def f(self): print self
...
>>> ob = A()
>>> A.f = f
>>> ob.g = f
>>> print ob.f
<bound method A.f of <__main__.A object at 0xb74204ec>>
>>> print ob.g
<function f at 0xb7412ae4>
>>> ob.f()
<__main__.A object at 0xb74204ec>
>>> ob.g('test')
test
Since A
is a class, f
, A().f
and A.f
are different things. Since ob
is an object, f
and ob.g
are the same thing.
因为A是一个类,f ()f和A。f是不同的东西。因为ob是一个对象,所以f和ob.g是一样的。
#5
1
because the function say_hi()
wasn't defined inside of the person class it doesn't know what self
is, and when you call it it isn't passing self
to the method. This would be like calling a static method.
因为函数say_hi()在person类中没有定义,所以它不知道self是什么,当你调用它时,它不会将self传递给方法。这就像调用一个静态方法。
you could do this though
你可以这么做
me=Person()
me.say_hi=say_hi
me.say_hi(me)
#6
1
No, self is not automatically passed to the object, because it has not been defined within the class block. Instead, you have defined a function, say_hi, in the wrong block. When you run it, 'self' in this context, is actually the first parameter of a function which is outside the class block, and therefore not a part of the class, hence the error.
不,self不会自动传递给对象,因为它没有在类块中定义。相反,您在错误的块中定义了一个函数say_hi。当您运行它时,“self”实际上是位于类块之外的函数的第一个参数,因此不是类的一部分,因此会出现错误。
#7
0
i think you wanted to do this
我觉得你想这么做。
say_hi(me)
but the usual way to program OO is this:
但是通常的编程方式是这样的:
class Person:
def say_hi(self):
print 'hii'
me = Person()
me.say_hi()
#8
0
maybe this works?
也许这个工作吗?
class Person():
def say_hi(self):
print 'hii'
me=Person()
me.say_hi()
I put the function inside the class because I feel thats what you wanted. Then you can call it later from the class object me.
我把函数放在类中,因为我觉得这就是你想要的。然后您可以稍后从类对象me调用它。
#1
6
(This can act as some demonstration for aaronasterling's answer.)
(这可以为aaronasterling的回答提供一些示范。)
Here are the definitions:
这是定义:
>>> class Person(object):
... def bound(self):
... print "Hi, I'm bound."
...
>>> def unbound(self):
... print "Hi, I'm unbound."
...
Note the types of these methods and functions.
注意这些方法和函数的类型。
>>> type(Person.bound)
<type 'instancemethod'>
>>> type(Person().bound)
<type 'instancemethod'>
>>> type(unbound)
<type 'function'>
>>> Person.unbound = unbound
When it gets set on the Person
before instantiation, it gets bound.
在实例化之前,当它在Person上设置时,它就被绑定。
>>> Person().bound()
Hi, I'm bound.
>>> Person().unbound()
Hi, I'm unbound.
However, if it's set after instantiation, it's still of type 'function'.
但是,如果在实例化之后设置它,它仍然是“function”类型。
>>> me = Person()
>>> me.rebound = unbound
>>> type(me.rebound)
<type 'function'>
>>> type(me.unbound)
<type 'instancemethod'>
>>> me.rebound
<function unbound at 0x7fa05efac9b0>
>>> me.rebound()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound() takes exactly 1 argument (0 given)
The 'instancemethod' type can be used to bind a 'function' to an object. It's in the types
module as MethodType
.
“instancemethod”类型可用于将“function”绑定到对象。它在types模块中作为MethodType。
>>> import types
>>> me.rebound = types.MethodType(unbound, me, Person)
Now it's bound properly.
现在是正确。
>>> type(me.rebound)
<type 'instancemethod'>
>>> me.rebound()
Hi, I'm unbound.
>>> # Not true any more!
#2
12
It's not passed in the way that you are doing it.
这不是你做这件事的方式。
You would have to do.
你必须这么做。
import types
me.say_hi = types.MethodType(say_hi, me, Person)
for it to work.
为它工作。
When python instantiates a class, it essentially carries out the above procedure for each of the class methods. When you 'monkey-patch' a method onto an object in the way that you were trying to do it, it's not a bound method and just exists as a function in instance.__dict__
. Calling it is no different than calling any other function. If you want to stick a method on an instance, you have to manually make it a method as shown above.
当python实例化一个类时,它实质上是为每个类方法执行上述过程。当你在一个对象上“monkey-patch”一个方法时,它并不是一个绑定方法,而是作为一个函数存在于instance.__dict__中。调用它与调用任何其他函数没有区别。如果您想在一个实例上粘贴一个方法,您必须手动地将其作为一个方法,如上面所示。
If you were to do
如果你要这么做的话
class Person(object):
pass
def say_hi(self):
print 'hii'
Person.say_hi = say_hi
me = Person()
me.say_hi()
then it would work because Python will create the method for you.
然后它会工作,因为Python会为您创建方法。
Chris Morgan put up an answer that shows this one in action. It's good stuff.
克里斯·摩根给出的答案显示了这一点。这是好东西。
#3
3
In this case say_hi is not method of your class. It is just reference to a function. This is why the self argument is not passed automatically.
在这种情况下,say_hi不是类的方法。它只是一个函数的引用。这就是为什么self参数不会自动传递。
Or just use:
或者只是使用:
class Person():
def say_hi(self):
print 'hii'
me=Person() me.say_hi=say_hi me.say_hi()
#4
1
The self argument of a method is passed automatically. You don't have a method, but a function that is an attribute of an object. If you did Person.say_hi = say_hi
, then Person().say_hi() would work as expected. A method is a function that's attribute of a class, not an instance, and self is passed only for methods.
方法的self参数将自动传递。你没有一个方法,但是一个函数是一个对象的属性。如果你的人。say_hi = say_hi,然后Person().say_hi()会像预期的那样工作。方法是类的属性,而不是实例,而self仅用于方法。
Class attributes define how the instances should work, while instance attributes are just normal you access. This means that class attributes are modified when they are accessed from an instance (e.g. functions are turned into methods), while instance attributes are left unchanged.
类属性定义实例应该如何工作,而实例属性只是您访问的普通属性。这意味着类属性在从实例访问时被修改(例如,函数被转换为方法),而实例属性则保持不变。
>>> class A(object): pass
...
>>> def f(self): print self
...
>>> ob = A()
>>> A.f = f
>>> ob.g = f
>>> print ob.f
<bound method A.f of <__main__.A object at 0xb74204ec>>
>>> print ob.g
<function f at 0xb7412ae4>
>>> ob.f()
<__main__.A object at 0xb74204ec>
>>> ob.g('test')
test
Since A
is a class, f
, A().f
and A.f
are different things. Since ob
is an object, f
and ob.g
are the same thing.
因为A是一个类,f ()f和A。f是不同的东西。因为ob是一个对象,所以f和ob.g是一样的。
#5
1
because the function say_hi()
wasn't defined inside of the person class it doesn't know what self
is, and when you call it it isn't passing self
to the method. This would be like calling a static method.
因为函数say_hi()在person类中没有定义,所以它不知道self是什么,当你调用它时,它不会将self传递给方法。这就像调用一个静态方法。
you could do this though
你可以这么做
me=Person()
me.say_hi=say_hi
me.say_hi(me)
#6
1
No, self is not automatically passed to the object, because it has not been defined within the class block. Instead, you have defined a function, say_hi, in the wrong block. When you run it, 'self' in this context, is actually the first parameter of a function which is outside the class block, and therefore not a part of the class, hence the error.
不,self不会自动传递给对象,因为它没有在类块中定义。相反,您在错误的块中定义了一个函数say_hi。当您运行它时,“self”实际上是位于类块之外的函数的第一个参数,因此不是类的一部分,因此会出现错误。
#7
0
i think you wanted to do this
我觉得你想这么做。
say_hi(me)
but the usual way to program OO is this:
但是通常的编程方式是这样的:
class Person:
def say_hi(self):
print 'hii'
me = Person()
me.say_hi()
#8
0
maybe this works?
也许这个工作吗?
class Person():
def say_hi(self):
print 'hii'
me=Person()
me.say_hi()
I put the function inside the class because I feel thats what you wanted. Then you can call it later from the class object me.
我把函数放在类中,因为我觉得这就是你想要的。然后您可以稍后从类对象me调用它。