类方法和实例方法之间的区别 [英] difference between class methods and instance methods

查看:65
本文介绍了类方法和实例方法之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我过去做过一些C ++和Java,并且最近学到了相当数量的Python。有一点我仍然无法获得

是类方法和实例方法之间的区别。我希望我能尝试将其缩小到几个具体的问题,但

非常感谢任何有关该主题的进一步投入:


1.我班上的所有方法都应该以''self''作为他们的首饰吗?


2.我是否应该使用MyClass.foo()来代替他们:


bar = MyClass()

bar.foo()




3.是绑定方法吗?实例方法的同义词?


4.是否为未绑定方法类方法的同义词?


如果有人*真的*大胆:

所谓的静态方法在哪里?适合所有这些?

根据它们的名称,它听起来和班级一样

方法...


非常感谢,

--- J


-

---如果通过电子邮件回复,删除zees - -

解决方案

John M. Gabriele写道:

1.我班上的所有方法都应该采用自我作为他们的第一个arg?


如果按类的方法你的意思是你叫做
classmethod的方法,然后不,他们不应该采用''self''参数,他们

应该采取''cls' '参数因为函数的第一个参数

将是类:


class C(object):

@classmethod

def f(cls,* args):

#do stuff


未修饰的方法(例如那些没有包裹的方法)另一方面,classmethod或

staticmethod)应该采用''self''参数。

2.我是否应该用MyClass.foo调用它们( )或者代之以:

bar = MyClass()
bar.foo()


应该从类中调用类方法。 Python允许你从实例中调用

,但这几乎从来没有你想要的,例如:


py> d = {}

py> d.fromkeys(范围(4))

{0:无,1:无,2:无,3:无}

py> d $ / $
{}


注意''d''没有更新 - 我叫了一个类方法,而不是

instancemethod。如果我改为调用dict.fromkeys,那么

会更清楚。

3.是绑定方法吗?实例方法的同义词?

4.是未绑定方法吗?类方法的同义词?


编号为了简化一些事情[1],一个绑定方法。是一个与特定实例关联的实例

方法,以及

未绑定方法是一个与特定实例没有关联的实例方法。考虑str.join和''''之间的区别.join:


py> str.join

< method''加入'''str''对象>

py> '',''。join

< str对象的内置方法连接位于0x01233620>

py> str.join(['''',''b'',''c''])

回溯(最近一次调用最后一次):

文件" ;<交互式输入>",第1行,在?

TypeError:描述符''join''需要''str''对象但收到''列表''

py> '',''。join(['''',''b'',''c''])

''a,b,c''

py> str.join('','',['''',''b'',''c''])

''a,b,c''


在上面的例子中,你可以看到str.join是一个未绑定的方法

- 当我尝试调用它而不给它一个实例时,抱怨。

另一方面,'',''。join是一种绑定方法。因为它已经绑定到特定的str实例(在这种情况下,实例'','')。

当我在没有实例的情况下调用它时,它并没有抱怨,因为它已经绑定到一个实例了。

所谓的静态方法在哪里?适合所有这些?
以他们的名义,它听起来像班级
方法一样......




Staticmethods,like classmethods,与类对象相关联,

不是实例对象。主要区别在于,当调用

staticmethod时,不会提供额外的参数,而当调用

a classmethod时,第一个参数(类)被插入到

参数列表:


py> C级(对象):

.... @classmethod

.... def f(* args):

...打印args

.... @staticmethod

.... def g(* args):

.... print args

....

py> C.f(1,2,3)

(< class''__ main __。C''>,1,2,3)

py> Cg(1,2,3)

(1,2,3)


STeVe


[1从技术上讲,我认为classmethods也可以被认为是绑定

方法。因为在这种情况下,该方法与''type''(它所在的类)的特定

实例相关联 - 你可以看到这个

in第一个参数提供给

类方法的参数列表。


John M. Gabriele写道:

我过去做过一些C ++和Java,并且最近学到了相当多的Python。有一件事我仍然无法获得
是类方法和实例方法之间的区别。我猜想我会尝试将其缩小到几个具体的问题,但是对于这个主题提供的任何进一步的输入都非常感谢:


我我会尽量不要像史蒂文在答复中所做的那样掩饰。

1.我所有班级的方法都应该以''自我'为他们的
第一个arg?
考虑这个:

class Demo(object):
def foo(self,x):< br $> b $ b打印自己,x

@classmethod

def clsmethod(cls,x):

print cls,x < br $>
@staticmethod

def stmethod(x):

print x


instance = Demo()


调用绑定方法,你不会传递一个显式的自我参数,但是

方法会收到一个自我参数:

bound = instance.foo
bound(2)
< __ main __。0x00B436B0处的演示对象> 2


请注意,无论是直接调用instance.foo(2)还是

首先将instance.foo绑定到变量。要么创建一个* new * bound

方法对象,并使用正确的实例进行调用。这是与b ++和Javascript等语言明显不同的,如果你想用一种方法作为回调,那么这真是一种痛苦。


调用一个未绑定的方法,你明确地传递一个self参数(并且它必须是一个类的实例,*或者一个子类的实例*:

unbound = Demo.foo
unbound(instance,2)
< __ main __。演示对象位于0x00B436B0> 2


再次无关紧要你可以在一两步中完成这个。通常的

使用未绑定方法的情况是你在一个

派生类中重写了一个方法并希望传递这个调用一个基类。例如

class Derived(Demo):
def foo(self,x):

Demo.foo(self,x)


类方法通常通过类而不是实例来调用,

并且它将第一个参数作为调用中涉及的实际类:

Demo.clsmethod(2)
< cl屁股''__主__。演示''> 2 Derived.clsmethod(2)
< class''_ _ main __。派生''> 2


您可以使用类的实例或

子类调用类方法,但仍然将get类作为第一个参数传递相比

比实例:

d =派生
d.clsmethod(2)
< class''_ _ main __。派生''> 2

类方法的一个常见用途是编写工厂函数。这是

,因为您可以确保创建的对象与第一个参数中传递的

参数具有相同的类。或者,您可以使用类

方法来控制与特定类相关的状态(例如,计算已创建的那个确切类的实例的数量。) />

在C ++中没有等效的类方法。


静态方法就像C ++中的静态方法。您可以通过

类或子类,或通过实例调用它们,但

调用中使用的对象不会传递给方法:

Demo.stmethod(2)
2 instance.stmethod(2)
2 Derived.stmethod(2)
2 d.stmethod(2)
2



2.我是否应该使用MyClass.foo()来代替他们:

bar = MyClass()
bar.foo()



如果您有实例,请使用它。如果类方法是工厂那么

你可能想要创建一个与现有的

对象相同类型的新对象(但不是简单的副本,因为你赢了'得到任何原始的

对象'的状态)。大多数情况下,你知道你想要创建的对象的类型,而不是现有的实例。

3.是绑定方法吗?实例方法的同义词?


关闭但不完全。它是一个(通常是瞬态的)对象,它是从一个

未绑定的实例方法创建的,用于调用该方法。
4.是否是未绑定的方法。类方法的同义词?


绝对不是。

如果有人*真的*大胆:
所谓的静态方法在哪里?适合所有这些?
以他们的名义,它听起来像班级
方法一样......




见上文。


Steven Bethard写道:

John M. Gabriele写道:

1我所有班级的方法都应该以自我作为他们的第一个arg吗?

如果通过类的方法你的意思是你调用类方法的方法,然后不,他们不应该采用''self''参数,他们应该采用''cls''参数,因为第一个参数是功能
将是班级:

C类(对象):
@classmethod
def f(cls,* args):
#do stuff




对不起 - 我不像你怀疑的那么远。 :)我已经

从未见过这个@ classmethod句法。我在假设它是这个所谓的新风格的一部分。类语法。


当我问我所有班级的方法都是......时,我的意思是,当

我是写一个类陈述和def'在其中 - 是

所有那些def'应该把''self''作为他们的第一个arg。


从你的回复中,我收集到了,除非我使用这种特殊的

语法(@classmethod或@staticmethod),否则所有的def都应该是

将''self''作为他们的第一个arg。

未修饰的方法(例如那些没有用classmethod或
staticmethod包装的方法)另一方面应该采取'' '自''参数。


好​​的。检查。


那么,这些都是def'的 - 将''self''作为他们的第一个 -

参数 - 在一个class语句,实例方法?

2.我是否应该使用MyClass.foo()来代替它们:

bar = MyClass()
bar.foo()



应该从类中调用Classmethods。 Python允许你从实例中调用它们,但这几乎从来没有你想要的,例如:

py> d = {}
py> d.fromkeys(范围(4))
{0:无,1:无,2:无,3:无}
py> d
{}

请注意,d未更新 - 我调用了类方法,而不是
实例方法。如果我打电话给dict.fromkeys,那就更清楚了。




对。 C ++中的一个重要教训。

3.是绑定方法吗?实例方法的同义词?

4.是未绑定方法吗?类方法的同义词?



编号为了简化一点[1],一个绑定方法。是与特定实例关联的实例
方法,以及
未绑定方法。是一个未与特定实例相关联的实例方法。




好​​的!现在我正在取得一些进展。 *这个*在饼干的关键点上得到了




考虑str.join和''''之间的区别.join:

py> str.join
< method''加入'''str''对象>

py> '',''。join
<内置方法连接str对象在0x01233620>


嗯...很奇怪。

PY> str.join(['''',''b'',''c''])
Traceback(最近一次调用最后一次):
文件"< interactive input>" ,第1行,在?
TypeError:描述符''join''需要一个''str''对象但收到''列表''


右 - ' '因为没有实际的字符串实例

来加入。检查。

py> '',''。join(['''',''b'',''c''])
''a,b,c''


检查。

py> str.join('','',['''',''b'',''c''])
''a,b,c''

Ack!现在你正在爬我。查看str.join的文档:


| PY>帮助(str.join)

| method_descriptor上的帮助:

|

|加入(...)

| S.join(序列) - > string

|

|返回一个字符串,它是

|中字符串的串联序列。元素之间的分隔符是S.

|


它表示你没有正确地调用该方法。然而

无论如何都有效!?这里发生了什么?


在上面的示例中,您可以看到str.join是一种未绑定的方法
- 当我尝试调用它时它没有给它一个实例,它抱怨道。另一方面,'',''。join是一种绑定方法。因为它已经绑定到str的特定实例(在这种情况下,实例'','')。当我在没有实例的情况下调用它时,它并没有抱怨,因为它已经被绑定到一个实例。


好​​的。我看到了这种区别。谢谢。

所谓的静态方法在哪里?适合所有这些?
以他们的名义,它听起来像班级
方法一样......



Staticmethods,如classmethods,是关联的使用类对象,
不是实例对象。




这是有道理的。

主要区别在于当<调用了staticmethod,没有提供额外的参数,而当调用classmethod时,第一个参数,类,被插入到
参数列表中:

PY> C级(对象):
... @classmethod
... def f(* args):
... print args
... @staticmethod ... def g(* args):
... print args
...
py> C.f(1,2,3)
(< class''__ main __。C''>,1,2,3)
py> C.g(1,2,3)
(1,2,3)

STeVe


谢谢你的好例子。看起来你总是

应该通过类来调用类和静态方法

名称(而不是实例名称)。我会读到这个新的@classmethod和@staticmethod语法意味着什么



[1]从技术上讲,我认为类方法也可以被认为是绑定的
方法因为在这种情况下,该方法与''type''(它所在的类)的特定
实例相关联 - 你可以在提供给它的第一个参数中看到这个
一个
classmethod的参数列表。




-

---如果通过电子邮件回复删除zees ---


I''ve done some C++ and Java in the past, and have recently learned
a fair amount of Python. One thing I still really don''t get though
is the difference between class methods and instance methods. I
guess I''ll try to narrow it down to a few specific questions, but
any further input offered on the subject is greatly appreciated:

1. Are all of my class''s methods supposed to take ''self'' as their
first arg?

2. Am I then supposed to call them with MyClass.foo() or instead:

bar = MyClass()
bar.foo()
?

3. Is "bound method" a synonym for instance method?

4. Is "unbound method" a synonym for class method?

And if anyone''s *really* daring:
Where do the so-called "static methods" fit into all this?
By the name of them, it sounds like the same thing as class
methods...

Much thanks,
---J

--
--- if replying via email, remove zees ---

解决方案

John M. Gabriele wrote:

1. Are all of my class''s methods supposed to take ''self'' as their
first arg?
If by "class''s methods" you mean methods on which you called
classmethod, then no, they shouldn''t take a ''self'' parameter, they
should take a ''cls'' parameter because the first argument to the function
will be the class:

class C(object):
@classmethod
def f(cls, *args):
# do stuff

Undecorated methods (e.g. those that are not wrapped with classmethod or
staticmethod) should, on the other hand, take a ''self'' parameter.
2. Am I then supposed to call them with MyClass.foo() or instead:

bar = MyClass()
bar.foo()
Classmethods should be called from the class. Python allows you to call
them from the instance, but this almost never does what you want, e.g.:

py> d = {}
py> d.fromkeys(range(4))
{0: None, 1: None, 2: None, 3: None}
py> d
{}

Note that ''d'' is not updated -- I called a classmethod, not an
instancemethod. If I had called dict.fromkeys instead, this would have
been clearer.
3. Is "bound method" a synonym for instance method?

4. Is "unbound method" a synonym for class method?
No. To simplify things a little[1], a "bound method" is an instance
method that has been associated with a specific instance, and an
"unbound method" is an instance method that has not been associated with
a specific instance. Consider the difference between str.join and ''''.join:

py> str.join
<method ''join'' of ''str'' objects>
py> '', ''.join
<built-in method join of str object at 0x01233620>
py> str.join([''a'', ''b'', ''c''])
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: descriptor ''join'' requires a ''str'' object but received a ''list''
py> '', ''.join([''a'', ''b'', ''c''])
''a, b, c''
py> str.join('', '', [''a'', ''b'', ''c''])
''a, b, c''

In the example above, you can see that str.join is an "unbound method"
-- when I try to call it without giving it an instance, it complains.
On the other hand, '', ''.join is a "bound method" because it has been
bound to a specific instance of str (in this case, the instance '', '').
When I call it without an instance, it doesn''t complain because it''s
already been bound to an instance.
Where do the so-called "static methods" fit into all this?
By the name of them, it sounds like the same thing as class
methods...



Staticmethods, like classmethods, are associated with the class object,
not the instance objects. The main difference is that when a
staticmethod is called, no additional arguments are supplied, while when
a classmethod is called, a first argument, the class, is inserted in the
argument list:

py> class C(object):
.... @classmethod
.... def f(*args):
.... print args
.... @staticmethod
.... def g(*args):
.... print args
....
py> C.f(1, 2, 3)
(<class ''__main__.C''>, 1, 2, 3)
py> C.g(1, 2, 3)
(1, 2, 3)

STeVe

[1] Technically, I think classmethods could also considered to be "bound
methods" because in this case, the method is associated with a specific
instance of ''type'' (the class in which it resides) -- you can see this
in the first argument that is supplied to the argument list of a
classmethod.


John M. Gabriele wrote:

I''ve done some C++ and Java in the past, and have recently learned
a fair amount of Python. One thing I still really don''t get though
is the difference between class methods and instance methods. I
guess I''ll try to narrow it down to a few specific questions, but
any further input offered on the subject is greatly appreciated:
I''ll try not to cover the same ground as Steven did in his reply.

1. Are all of my class''s methods supposed to take ''self'' as their
first arg? consider this:

class Demo(object): def foo(self, x):
print self, x
@classmethod
def clsmethod(cls, x):
print cls, x
@staticmethod
def stmethod(x):
print x

instance = Demo()
Calling a bound method, you don''t pass an explicit self parameter, but the
method receives a self parameter:
bound = instance.foo
bound(2) <__main__.Demo object at 0x00B436B0> 2

Note that it doesn''t matter whether you call instance.foo(2) directly, or
bind instance.foo to a variable first. Either will create a *new* bound
method object, and the correct instance is used for the call. This is
significantly different from languages such as C++ and Javascript which are
a real pain if you want to use a method as a callback.

Calling an unbound method, you pass a self parameter explicitly (and it
must be an instance of the class, *or an instance of a subclass*:
unbound = Demo.foo
unbound(instance, 2) <__main__.Demo object at 0x00B436B0> 2

Again is doesn''t matter whether you do this in one step or two. The usual
case for using an unbound method is when you have overridden a method in a
derived class and want to pass the call on to a base class. e.g.
class Derived(Demo): def foo(self, x):
Demo.foo(self, x)

A class method is usually called through the class rather than an instance,
and it gets as its first parameter the actual class involved in the call:
Demo.clsmethod(2) <class ''__main__.Demo''> 2 Derived.clsmethod(2) <class ''__main__.Derived''> 2

You can call a class method using an instance of the class, or of a
subclass, but you still the get class passed as the first parameter rather
than the instance:
d = Derived
d.clsmethod(2) <class ''__main__.Derived''> 2

A common use for class methods is to write factory functions. This is
because you can ensure that the object created has the same class as the
parameter passed in the first argument. Alternatively you can use class
methods to control state related to a specific class (e.g. to count the
number of instances of that exact class which have been created.)

There is no equivalent to a class method in C++.

Static methods are like static methods in C++. You can call them through
the class or a subclass, or through an instance, but the object used in the
call is not passed through to the method:
Demo.stmethod(2) 2 instance.stmethod(2) 2 Derived.stmethod(2) 2 d.stmethod(2) 2



2. Am I then supposed to call them with MyClass.foo() or instead:

bar = MyClass()
bar.foo()
?
If you have an instance then use it. If the class method is a factory then
you might want to create a new object of the same type as some existing
object (but not a simple copy since you won''t get any of the original
object''s state). Mostly though you know the type of the object you want to
create rather than having an existing instance lying around.

3. Is "bound method" a synonym for instance method?
Close but not quite. It is a (usually transient) object created from an
unbound instance method for the purposes of calling the method.
4. Is "unbound method" a synonym for class method?
Definitely not.

And if anyone''s *really* daring:
Where do the so-called "static methods" fit into all this?
By the name of them, it sounds like the same thing as class
methods...



See above.


Steven Bethard wrote:

John M. Gabriele wrote:

1. Are all of my class''s methods supposed to take ''self'' as their
first arg?

If by "class''s methods" you mean methods on which you called
classmethod, then no, they shouldn''t take a ''self'' parameter, they
should take a ''cls'' parameter because the first argument to the function
will be the class:

class C(object):
@classmethod
def f(cls, *args):
# do stuff



Sorry -- I''m not as far along as you suspect. :) I''ve
never yet seen this "@classmethod" syntax. I''m supposing that
it''s part of this so-called "new-style" class syntax.

When I ask "are all my class''s methods...", I mean, when
I''m writing a class statement and the def''s therein -- are
all those def''s supposed to take ''self'' as their first arg.

From your reply, I gather that, unless I''m using this special
syntax (@classmethod or @staticmethod), all my def''s are supposed
to take ''self'' as their first arg.
Undecorated methods (e.g. those that are not wrapped with classmethod or
staticmethod) should, on the other hand, take a ''self'' parameter.
Ok. Check.

So then, are all def''s -- that take ''self'' as their first --
argument -- in a class statement, instance methods?

2. Am I then supposed to call them with MyClass.foo() or instead:

bar = MyClass()
bar.foo()


Classmethods should be called from the class. Python allows you to call
them from the instance, but this almost never does what you want, e.g.:

py> d = {}
py> d.fromkeys(range(4))
{0: None, 1: None, 2: None, 3: None}
py> d
{}

Note that ''d'' is not updated -- I called a classmethod, not an
instancemethod. If I had called dict.fromkeys instead, this would have
been clearer.



Right. An important lesson in C++ as well.

3. Is "bound method" a synonym for instance method?

4. Is "unbound method" a synonym for class method?


No. To simplify things a little[1], a "bound method" is an instance
method that has been associated with a specific instance, and an
"unbound method" is an instance method that has not been associated with
a specific instance.



Ok! Now I''m making some headway. *This* is getting
at the crux of the biscuit.

Consider the difference between str.join and ''''.join:

py> str.join
<method ''join'' of ''str'' objects>

py> '', ''.join
<built-in method join of str object at 0x01233620>

Hmm... weird.
py> str.join([''a'', ''b'', ''c''])
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: descriptor ''join'' requires a ''str'' object but received a ''list''

Right -- ''cause there''s no actual instance of a string
to do the joining. Check.
py> '', ''.join([''a'', ''b'', ''c''])
''a, b, c''
Check.
py> str.join('', '', [''a'', ''b'', ''c''])
''a, b, c''
Ack! Now you''re creeping me out. Looking at the doc for str.join:

| py> help( str.join )
| Help on method_descriptor:
|
| join(...)
| S.join(sequence) -> string
|
| Return a string which is the concatenation of the strings in the
| sequence. The separator between elements is S.
|

It says that you didn''t call that method correctly. Yet
it works anyway!? What''s happening here?

In the example above, you can see that str.join is an "unbound method"
-- when I try to call it without giving it an instance, it complains. On
the other hand, '', ''.join is a "bound method" because it has been bound
to a specific instance of str (in this case, the instance '', ''). When I
call it without an instance, it doesn''t complain because it''s already
been bound to an instance.
Ok. I see that distinction. Thanks.

Where do the so-called "static methods" fit into all this?
By the name of them, it sounds like the same thing as class
methods...


Staticmethods, like classmethods, are associated with the class object,
not the instance objects.



That makes sense.
The main difference is that when a
staticmethod is called, no additional arguments are supplied, while when
a classmethod is called, a first argument, the class, is inserted in the
argument list:

py> class C(object):
... @classmethod
... def f(*args):
... print args
... @staticmethod
... def g(*args):
... print args
...
py> C.f(1, 2, 3)
(<class ''__main__.C''>, 1, 2, 3)
py> C.g(1, 2, 3)
(1, 2, 3)

STeVe
Thanks for that nice example. It looks like you''re always
supposed to call both class and static methods via the class
name (rather than an instance name). I''ll read up on what
this new @classmethod and @staticmethod syntax means.
[1] Technically, I think classmethods could also considered to be "bound
methods" because in this case, the method is associated with a specific
instance of ''type'' (the class in which it resides) -- you can see this
in the first argument that is supplied to the argument list of a
classmethod.



--
--- remove zees if replying via email ---


这篇关于类方法和实例方法之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆