问题:类方法的目的是什么?
我正在自学Python,最近的类是Python不是Java,因此我花了一段时间将所有Class方法都转换为函数。
我现在意识到我不需要使用Class方法来完成static
Java中的方法,但是现在我不确定何时使用它们。我可以找到的有关Python类方法的所有建议都是像我这样的新手提出的,应该避免使用它们,并且在讨论它们时,标准文档最为模糊。
有没有人有在Python中使用Class方法的好例子,或者至少有人可以告诉我何时可以明智地使用Class方法?
I’m teaching myself Python and my most recent lesson was that Python is not Java, and so I’ve just spent a while turning all my Class methods into functions.
I now realise that I don’t need to use Class methods for what I would done with static
methods in Java, but now I’m not sure when I would use them. All the advice I can find about Python Class methods is along the lines of newbies like me should steer clear of them, and the standard documentation is at its most opaque when discussing them.
Does anyone have a good example of using a Class method in Python or at least can someone tell me when Class methods can be sensibly used?
回答 0
类方法用于需要不特定于任何特定实例但仍以某种方式涉及到类的方法。关于它们的最有趣的事情是它们可以被子类覆盖,这在Java的静态方法或Python的模块级函数中根本是不可能的。
如果您有一个类MyClass
,以及一个在MyClass上运行的模块级函数(工厂,依赖项注入存根等),请将其设置为classmethod
。然后它将对子类可用。
Class methods are for when you need to have methods that aren’t specific to any particular instance, but still involve the class in some way. The most interesting thing about them is that they can be overridden by subclasses, something that’s simply not possible in Java’s static methods or Python’s module-level functions.
If you have a class MyClass
, and a module-level function that operates on MyClass (factory, dependency injection stub, etc), make it a classmethod
. Then it’ll be available to subclasses.
回答 1
工厂方法(替代构造函数)确实是类方法的经典示例。
基本上,类方法适合任何您想自然地适合于类的命名空间但不与类的特定实例相关联的方法。
例如,在出色的unipath模块中:
当前目录
Path.cwd()
- 返回实际的当前目录;例如
Path("/tmp/my_temp_dir")
。这是一个类方法。
.chdir()
由于当前目录是进程范围的,因此该cwd
方法没有应与之关联的特定实例。但是,将更cwd
改为给定Path
实例的目录确实应该是一个实例方法。
嗯… Path.cwd()
确实确实返回了一个Path
实例,我想它可以被认为是工厂方法…
Factory methods (alternative constructors) are indeed a classic example of class methods.
Basically, class methods are suitable anytime you would like to have a method which naturally fits into the namespace of the class, but is not associated with a particular instance of the class.
As an example, in the excellent unipath module:
Current directory
Path.cwd()
- Return the actual current directory; e.g.,
Path("/tmp/my_temp_dir")
. This is a class method.
.chdir()
- Make self the current directory.
As the current directory is process wide, the cwd
method has no particular instance with which it should be associated. However, changing the cwd
to the directory of a given Path
instance should indeed be an instance method.
Hmmm… as Path.cwd()
does indeed return a Path
instance, I guess it could be considered to be a factory method…
回答 2
Think about it this way: normal methods are useful to hide the details of dispatch: you can type myobj.foo()
without worrying about whether the foo()
method is implemented by the myobj
object’s class or one of its parent classes. Class methods are exactly analogous to this, but with the class object instead: they let you call MyClass.foo()
without having to worry about whether foo()
is implemented specially by MyClass
because it needed its own specialized version, or whether it is letting its parent class handle the call.
Class methods are essential when you are doing set-up or computation that precedes the creation of an actual instance, because until the instance exists you obviously cannot use the instance as the dispatch point for your method calls. A good example can be viewed in the SQLAlchemy source code; take a look at the dbapi()
class method at the following link:
https://github.com/zzzeek/sqlalchemy/blob/ab6946769742602e40fb9ed9dde5f642885d1906/lib/sqlalchemy/dialects/mssql/pymssql.py#L47
You can see that the dbapi()
method, which a database backend uses to import the vendor-specific database library it needs on-demand, is a class method because it needs to run before instances of a particular database connection start getting created — but that it cannot be a simple function or static function, because they want it to be able to call other, supporting methods that might similarly need to be written more specifically in subclasses than in their parent class. And if you dispatch to a function or static class, then you “forget” and lose the knowledge about which class is doing the initializing.
回答 3
我最近想要一个非常轻量级的日志记录类,该类将根据可以通过编程设置的日志记录级别输出不同数量的输出。但是我不想每次想输出调试消息,错误或警告时都实例化该类。但是我还想封装该日志记录工具的功能,并在不声明任何全局变量的情况下使其可重用。
因此,我使用了类变量和@classmethod
装饰器来实现这一点。
使用简单的Logging类,可以执行以下操作:
Logger._level = Logger.DEBUG
然后,在我的代码中,如果我想吐出一堆调试信息,我只需要编写代码
Logger.debug( "this is some annoying message I only want to see while debugging" )
错误可能会被解决
Logger.error( "Wow, something really awful happened." )
在“生产”环境中,我可以指定
Logger._level = Logger.ERROR
现在,将仅输出错误消息。调试消息将不会打印。
这是我的课:
class Logger :
''' Handles logging of debugging and error messages. '''
DEBUG = 5
INFO = 4
WARN = 3
ERROR = 2
FATAL = 1
_level = DEBUG
def __init__( self ) :
Logger._level = Logger.DEBUG
@classmethod
def isLevel( cls, level ) :
return cls._level >= level
@classmethod
def debug( cls, message ) :
if cls.isLevel( Logger.DEBUG ) :
print "DEBUG: " + message
@classmethod
def info( cls, message ) :
if cls.isLevel( Logger.INFO ) :
print "INFO : " + message
@classmethod
def warn( cls, message ) :
if cls.isLevel( Logger.WARN ) :
print "WARN : " + message
@classmethod
def error( cls, message ) :
if cls.isLevel( Logger.ERROR ) :
print "ERROR: " + message
@classmethod
def fatal( cls, message ) :
if cls.isLevel( Logger.FATAL ) :
print "FATAL: " + message
和一些测试它的代码:
def logAll() :
Logger.debug( "This is a Debug message." )
Logger.info ( "This is a Info message." )
Logger.warn ( "This is a Warn message." )
Logger.error( "This is a Error message." )
Logger.fatal( "This is a Fatal message." )
if __name__ == '__main__' :
print "Should see all DEBUG and higher"
Logger._level = Logger.DEBUG
logAll()
print "Should see all ERROR and higher"
Logger._level = Logger.ERROR
logAll()
I recently wanted a very light-weight logging class that would output varying amounts of output depending on the logging level that could be programmatically set. But I didn’t want to instantiate the class every time I wanted to output a debugging message or error or warning. But I also wanted to encapsulate the functioning of this logging facility and make it reusable without the declaration of any globals.
So I used class variables and the @classmethod
decorator to achieve this.
With my simple Logging class, I could do the following:
Logger._level = Logger.DEBUG
Then, in my code, if I wanted to spit out a bunch of debugging information, I simply had to code
Logger.debug( "this is some annoying message I only want to see while debugging" )
Errors could be out put with
Logger.error( "Wow, something really awful happened." )
In the “production” environment, I can specify
Logger._level = Logger.ERROR
and now, only the error message will be output. The debug message will not be printed.
Here’s my class:
class Logger :
''' Handles logging of debugging and error messages. '''
DEBUG = 5
INFO = 4
WARN = 3
ERROR = 2
FATAL = 1
_level = DEBUG
def __init__( self ) :
Logger._level = Logger.DEBUG
@classmethod
def isLevel( cls, level ) :
return cls._level >= level
@classmethod
def debug( cls, message ) :
if cls.isLevel( Logger.DEBUG ) :
print "DEBUG: " + message
@classmethod
def info( cls, message ) :
if cls.isLevel( Logger.INFO ) :
print "INFO : " + message
@classmethod
def warn( cls, message ) :
if cls.isLevel( Logger.WARN ) :
print "WARN : " + message
@classmethod
def error( cls, message ) :
if cls.isLevel( Logger.ERROR ) :
print "ERROR: " + message
@classmethod
def fatal( cls, message ) :
if cls.isLevel( Logger.FATAL ) :
print "FATAL: " + message
And some code that tests it just a bit:
def logAll() :
Logger.debug( "This is a Debug message." )
Logger.info ( "This is a Info message." )
Logger.warn ( "This is a Warn message." )
Logger.error( "This is a Error message." )
Logger.fatal( "This is a Fatal message." )
if __name__ == '__main__' :
print "Should see all DEBUG and higher"
Logger._level = Logger.DEBUG
logAll()
print "Should see all ERROR and higher"
Logger._level = Logger.ERROR
logAll()
回答 4
Alternative constructors are the classic example.
回答 5
当用户登录我的网站时,将从用户名和密码实例化User()对象。
如果我需要一个用户对象而不需要用户在那里登录(例如,管理员用户可能要删除另一个用户帐户,那么我需要实例化该用户并调用其delete方法):
我有获取用户对象的类方法。
class User():
#lots of code
#...
# more code
@classmethod
def get_by_username(cls, username):
return cls.query(cls.username == username).get()
@classmethod
def get_by_auth_id(cls, auth_id):
return cls.query(cls.auth_id == auth_id).get()
When a user logs in on my website, a User() object is instantiated from the username and password.
If I need a user object without the user being there to log in (e.g. an admin user might want to delete another users account, so i need to instantiate that user and call its delete method):
I have class methods to grab the user object.
class User():
#lots of code
#...
# more code
@classmethod
def get_by_username(cls, username):
return cls.query(cls.username == username).get()
@classmethod
def get_by_auth_id(cls, auth_id):
return cls.query(cls.auth_id == auth_id).get()
回答 6
我认为最明确的答案是AmanKow的答案。归结为您要如何组织代码。您可以将所有内容编写为模块级函数,并包装在模块的命名空间中,即
module.py (file 1)
---------
def f1() : pass
def f2() : pass
def f3() : pass
usage.py (file 2)
--------
from module import *
f1()
f2()
f3()
def f4():pass
def f5():pass
usage1.py (file 3)
-------------------
from usage import f4,f5
f4()
f5()
上面的过程代码没有很好的组织,正如您看到的只有3个模块感到困惑之后,每种方法有什么作用?您可以为函数使用长的描述性名称(例如Java中的名称),但您的代码仍然很快变得难以管理。
面向对象的方式是将代码分解为可管理的块,即类和对象以及函数可以与对象实例或类相关联。
与模块级别的函数相比,使用类函数可以在代码中获得更高的划分级别。因此,您可以在一个类中对相关功能进行分组,以使它们对您分配给该类的任务更加特定。例如,您可以创建一个文件实用程序类:
class FileUtil ():
def copy(source,dest):pass
def move(source,dest):pass
def copyDir(source,dest):pass
def moveDir(source,dest):pass
//usage
FileUtil.copy("1.txt","2.txt")
FileUtil.moveDir("dir1","dir2")
这种方式更灵活,更可维护,您可以将功能分组在一起,并且每个功能的作用更加明显。另外,还可以防止名称冲突,例如,函数副本可能存在于您在代码中使用的另一个导入模块(例如,网络副本)中,因此,当您使用全名FileUtil.copy()时,您就可以解决此问题并同时复制两个函数可以并排使用。
I think the most clear answer is AmanKow’s one. It boils down to how u want to organize your code. You can write everything as module level functions which are wrapped in the namespace of the module i.e
module.py (file 1)
---------
def f1() : pass
def f2() : pass
def f3() : pass
usage.py (file 2)
--------
from module import *
f1()
f2()
f3()
def f4():pass
def f5():pass
usage1.py (file 3)
-------------------
from usage import f4,f5
f4()
f5()
The above procedural code is not well organized, as you can see after only 3 modules it gets confusing, what is each method do ? You can use long descriptive names for functions(like in java) but still your code gets unmanageable very quick.
The object oriented way is to break down your code into manageable blocks i.e Classes & objects and functions can be associated with objects instances or with classes.
With class functions you gain another level of division in your code compared with module level functions. So you can group related functions within a class to make them more specific to a task that you assigned to that class. For example you can create a file utility class :
class FileUtil ():
def copy(source,dest):pass
def move(source,dest):pass
def copyDir(source,dest):pass
def moveDir(source,dest):pass
//usage
FileUtil.copy("1.txt","2.txt")
FileUtil.moveDir("dir1","dir2")
This way is more flexible and more maintainable, you group functions together and its more obvious to what each function do. Also you prevent name conflicts, for example the function copy may exist in another imported module(for example network copy) that you use in your code, so when you use the full name FileUtil.copy() you remove the problem and both copy functions can be used side by side.
回答 7
老实说 我从未找到用于staticmethod或classmethod的方法。我还没有看到使用全局函数或实例方法无法完成的操作。
如果python更像Java那样使用私有成员和受保护成员,那将是不同的。在Java中,我需要一个静态方法来访问实例的私有成员以执行操作。在Python中,这几乎没有必要。
通常,当人们真正需要做的就是更好地使用python的模块级命名空间时,我会看到人们使用staticmethod和classmethod。
Honestly? I’ve never found a use for staticmethod or classmethod. I’ve yet to see an operation that can’t be done using a global function or an instance method.
It would be different if python used private and protected members more like Java does. In Java, I need a static method to be able to access an instance’s private members to do stuff. In Python, that’s rarely necessary.
Usually, I see people using staticmethods and classmethods when all they really need to do is use python’s module-level namespaces better.
回答 8
它允许您编写可与任何兼容类一起使用的通用类方法。
例如:
@classmethod
def get_name(cls):
print cls.name
class C:
name = "tester"
C.get_name = get_name
#call it:
C.get_name()
如果您不使用@classmethod
它,可以使用self关键字来实现,但是它需要一个Class的实例:
def get_name(self):
print self.name
class C:
name = "tester"
C.get_name = get_name
#call it:
C().get_name() #<-note the its an instance of class C
It allows you to write generic class methods that you can use with any compatible class.
For example:
@classmethod
def get_name(cls):
print cls.name
class C:
name = "tester"
C.get_name = get_name
#call it:
C.get_name()
If you don’t use @classmethod
you can do it with self keyword but it needs an instance of Class:
def get_name(self):
print self.name
class C:
name = "tester"
C.get_name = get_name
#call it:
C().get_name() #<-note the its an instance of class C
回答 9
我曾经使用过PHP,最近又问自己,这种方法是怎么回事?Python手册非常技术性,而且措辞很短,因此对理解该功能没有帮助。我正在谷歌搜索,发现答案-> http://code.anjanesh.net/2007/12/python-classmethods.html。
如果您不愿意单击它。我的解释更短一些。:)
在PHP中(也许不是所有人都知道PHP,但是这种语言非常简单,每个人都应该理解我在说什么),我们有如下静态变量:
class A
{
static protected $inner_var = null;
static public function echoInnerVar()
{
echo self::$inner_var."\n";
}
static public function setInnerVar($v)
{
self::$inner_var = $v;
}
}
class B extends A
{
}
A::setInnerVar(10);
B::setInnerVar(20);
A::echoInnerVar();
B::echoInnerVar();
两种情况下的输出均为20。
但是在python中,我们可以添加@classmethod装饰器,因此有可能分别具有输出10和20。例:
class A(object):
inner_var = 0
@classmethod
def setInnerVar(cls, value):
cls.inner_var = value
@classmethod
def echoInnerVar(cls):
print cls.inner_var
class B(A):
pass
A.setInnerVar(10)
B.setInnerVar(20)
A.echoInnerVar()
B.echoInnerVar()
聪明吧?
I used to work with PHP and recently I was asking myself, whats going on with this classmethod? Python manual is very technical and very short in words so it wont help with understanding that feature. I was googling and googling and I found answer -> http://code.anjanesh.net/2007/12/python-classmethods.html.
If you are lazy to click it. My explanation is shorter and below. :)
in PHP (maybe not all of you know PHP, but this language is so straight forward that everybody should understand what I’m talking about) we have static variables like this:
class A
{
static protected $inner_var = null;
static public function echoInnerVar()
{
echo self::$inner_var."\n";
}
static public function setInnerVar($v)
{
self::$inner_var = $v;
}
}
class B extends A
{
}
A::setInnerVar(10);
B::setInnerVar(20);
A::echoInnerVar();
B::echoInnerVar();
The output will be in both cases 20.
However in python we can add @classmethod decorator and thus it is possible to have output 10 and 20 respectively. Example:
class A(object):
inner_var = 0
@classmethod
def setInnerVar(cls, value):
cls.inner_var = value
@classmethod
def echoInnerVar(cls):
print cls.inner_var
class B(A):
pass
A.setInnerVar(10)
B.setInnerVar(20)
A.echoInnerVar()
B.echoInnerVar()
Smart, ain’t?
回答 10
类方法提供“语义糖”(不知道此术语是否被广泛使用)或“语义便利”。
示例:您获得了一组表示对象的类。您可能需要类方法all()
或find()
编写User.all()
or User.find(firstname='Guido')
。当然可以使用模块级别的功能来完成…
Class methods provide a “semantic sugar” (don’t know if this term is widely used) – or “semantic convenience”.
Example: you got a set of classes representing objects. You might want to have the class method all()
or find()
to write User.all()
or User.find(firstname='Guido')
. That could be done using module level functions of course…
回答 11
刚从Ruby袭来的我是,所谓的类方法和所谓的实例方法只是一个函数,其第一个参数具有语义含义,当该函数被称为一个对象(即obj.meth()
)。
通常,该对象必须是实例,但是@classmethod
方法装饰器会更改规则以传递类。您可以在实例上调用类方法(它只是一个函数)-第一个参数将是其类。
因为它只是一个函数,所以只能在任何给定范围(即class
定义)中声明一次。因此,如果遵循的话,令Rubyist感到惊讶的是,您不能拥有同名的类方法和实例方法。
考虑一下:
class Foo():
def foo(x):
print(x)
您可以呼叫foo
执行个体
Foo().foo()
<__main__.Foo instance at 0x7f4dd3e3bc20>
但不在课堂上:
Foo.foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with Foo instance as first argument (got nothing instead)
现在添加@classmethod
:
class Foo():
@classmethod
def foo(x):
print(x)
现在,调用实例将传递其类:
Foo().foo()
__main__.Foo
就像上课一样:
Foo.foo()
__main__.Foo
唯一的约定规定我们self
在实例方法和cls
类方法上使用第一个参数。我在这里都没有用它来说明它只是一个论点。在Ruby中,self
是关键字。
与Ruby对比:
class Foo
def foo()
puts "instance method #{self}"
end
def self.foo()
puts "class method #{self}"
end
end
Foo.foo()
class method Foo
Foo.new.foo()
instance method #<Foo:0x000000020fe018>
Python类方法只是一个装饰函数,您可以使用相同的技术来创建自己的装饰器。装饰方法包装实际方法(如果@classmethod
它通过附加的类参数)。底层方法仍然存在,已隐藏但仍可访问。
脚注:我是在类和实例方法之间的名称冲突引起了我的好奇心之后写的。我距离Python专家还很远,如果其中任何一个错误,我想发表评论。
What just hit me, coming from Ruby, is that a so-called class method and a so-called instance method is just a function with semantic meaning applied to its first parameter, which is silently passed when the function is called as a method of an object (i.e. obj.meth()
).
Normally that object must be an instance but the @classmethod
method decorator changes the rules to pass a class. You can call a class method on an instance (it’s just a function) – the first argument will be its class.
Because it’s just a function, it can only be declared once in any given scope (i.e. class
definition). If follows therefore, as a surprise to a Rubyist, that you can’t have a class method and an instance method with the same name.
Consider this:
class Foo():
def foo(x):
print(x)
You can call foo
on an instance
Foo().foo()
<__main__.Foo instance at 0x7f4dd3e3bc20>
But not on a class:
Foo.foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with Foo instance as first argument (got nothing instead)
Now add @classmethod
:
class Foo():
@classmethod
def foo(x):
print(x)
Calling on an instance now passes its class:
Foo().foo()
__main__.Foo
as does calling on a class:
Foo.foo()
__main__.Foo
It’s only convention that dictates that we use self
for that first argument on an instance method and cls
on a class method. I used neither here to illustrate that it’s just an argument. In Ruby, self
is a keyword.
Contrast with Ruby:
class Foo
def foo()
puts "instance method #{self}"
end
def self.foo()
puts "class method #{self}"
end
end
Foo.foo()
class method Foo
Foo.new.foo()
instance method #<Foo:0x000000020fe018>
The Python class method is just a decorated function and you can use the same techniques to create your own decorators. A decorated method wraps the real method (in the case of @classmethod
it passes the additional class argument). The underlying method is still there, hidden but still accessible.
footnote: I wrote this after a name clash between a class and instance method piqued my curiosity. I am far from a Python expert and would like comments if any of this is wrong.
回答 12
这是一个有趣的话题。我认为python classmethod的操作方式像单例操作,而不是工厂操作(工厂返回一个产生的类实例)。之所以成为单例,是因为产生了一个公共对象(字典),但该类仅产生一次,但被所有实例共享。
为了说明这一点,这里是一个示例。请注意,所有实例均引用单个词典。据我了解,这不是工厂模式。这可能是python非常独特的。
class M():
@classmethod
def m(cls, arg):
print "arg was", getattr(cls, "arg" , None),
cls.arg = arg
print "arg is" , cls.arg
M.m(1) # prints arg was None arg is 1
M.m(2) # prints arg was 1 arg is 2
m1 = M()
m2 = M()
m1.m(3) # prints arg was 2 arg is 3
m2.m(4) # prints arg was 3 arg is 4 << this breaks the factory pattern theory.
M.m(5) # prints arg was 4 arg is 5
This is an interesting topic. My take on it is that python classmethod operates like a singleton rather than a factory (which returns a produced an instance of a class). The reason it is a singleton is that there is a common object that is produced (the dictionary) but only once for the class but shared by all instances.
To illustrate this here is an example. Note that all instances have a reference to the single dictionary. This is not Factory pattern as I understand it. This is probably very unique to python.
class M():
@classmethod
def m(cls, arg):
print "arg was", getattr(cls, "arg" , None),
cls.arg = arg
print "arg is" , cls.arg
M.m(1) # prints arg was None arg is 1
M.m(2) # prints arg was 1 arg is 2
m1 = M()
m2 = M()
m1.m(3) # prints arg was 2 arg is 3
m2.m(4) # prints arg was 3 arg is 4 << this breaks the factory pattern theory.
M.m(5) # prints arg was 4 arg is 5
回答 13
我几次问自己这个问题。即使这里的人们努力解释,恕我直言,我发现最好的答案(也是最简单的)是描述 Python文档中有关Class方法。
也有引用静态方法。如果有人已经知道实例方法(我假设),那么这个答案可能是将所有内容放在一起的最后一部分…
也可以在文档中找到有关此主题的更多详细说明: 标准类型层次结构(向下滚动至“ 实例方法”部分)
I was asking myself the same question few times. And even though the guys here tried hard to explain it, IMHO the best answer (and simplest) answer I have found is the description of the Class method in the Python Documentation.
There is also reference to the Static method. And in case someone already know instance methods (which I assume), this answer might be the final piece to put it all together…
Further and deeper elaboration on this topic can be found also in the documentation: The standard type hierarchy (scroll down to Instance methods section)
回答 14
@classmethod
从外部资源轻松实例化该类的对象很有用。考虑以下:
import settings
class SomeClass:
@classmethod
def from_settings(cls):
return cls(settings=settings)
def __init__(self, settings=None):
if settings is not None:
self.x = settings['x']
self.y = settings['y']
然后在另一个文件中:
from some_package import SomeClass
inst = SomeClass.from_settings()
访问inst.x将提供与settings [‘x’]相同的值。
@classmethod
can be useful for easily instantiating objects of that class from outside resources. Consider the following:
import settings
class SomeClass:
@classmethod
def from_settings(cls):
return cls(settings=settings)
def __init__(self, settings=None):
if settings is not None:
self.x = settings['x']
self.y = settings['y']
Then in another file:
from some_package import SomeClass
inst = SomeClass.from_settings()
Accessing inst.x will give the same value as settings[‘x’].
回答 15
当然,一个类定义了一组实例。一类的方法适用于各个实例。类方法(和变量)用于挂起与所有实例集相关的其他信息的位置。
例如,如果您的Class定义了一组学生,则您可能需要Class变量或方法来定义诸如学生可以成为其成员的年级组之类的东西。
您还可以使用类方法来定义用于处理整个集合的工具。例如,Student.all_of_em()可能会返回所有已知的学生。显然,如果您的实例集具有比一组实例更多的结构,则可以提供类方法来了解该结构。Students.all_of_em(grade =’juniors’)
诸如此类的技术往往导致将实例集的成员存储到以类变量为根的数据结构中。您需要注意避免破坏垃圾收集。
A class defines a set of instances, of course. And the methods of a class work on the individual instances. The class methods (and variables) a place to hang other information that is related to the set of instances over all.
For example if your class defines a the set of students you might want class variables or methods which define things like the set of grade the students can be members of.
You can also use class methods to define tools for working on the entire set. For example Student.all_of_em() might return all the known students. Obviously if your set of instances have more structure than just a set you can provide class methods to know about that structure. Students.all_of_em(grade=’juniors’)
Techniques like this tend to lead to storing members of the set of instances into data structures that are rooted in class variables. You need to take care to avoid frustrating the garbage collection then.
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。