适当的类初始化 [英] Proper class initialization
问题描述
通常,你初始化类变量:
class A:
sum = 45
但是如果它们是某些计算或处理的结果,则初始化类变量的正确方法是什么,如下面的愚蠢
示例(代表更多:
A级:
sum = 0
for i in range(10):
sum + =我是b $ b问题是这使得任何辅助变量(比如这个
愚蠢的例子中的i)也是类变量,这是不希望的。
当然,我可以调用类外部的函数
def calc_sum(n):
...
A级:
sum = calc_sum(10)
但我不知道是否是可以将所有这些初始化代码放入一个
类初始化方法,类似于:
A类:
@classmethod
def init_class(s精灵):
总和= 0
我在范围内(10):
总和+ = i
self.sum = sum
init_class()
然而,这不起作用,我得到
TypeError :''classmethod''对象不可调用
有没有另一种方法可以为A类放置一个初始化方法
某处*里面* A类?
- Christoph
Usually, you initialize class variables like that:
class A:
sum = 45
But what is the proper way to initialize class variables if they are the
result of some computation or processing as in the following silly
example (representative for more:
class A:
sum = 0
for i in range(10):
sum += i
The problem is that this makes any auxiliary variables (like "i" in this
silly example) also class variables, which is not desired.
Of course, I could call a function external to the class
def calc_sum(n):
...
class A:
sum = calc_sum(10)
But I wonder whether it is possible to put all this init code into one
class initialization method, something like that:
class A:
@classmethod
def init_class(self):
sum = 0
for i in range(10):
sum += i
self.sum = sum
init_class()
However, this does not work, I get
TypeError: ''classmethod'' object is not callable
Is there another way to put an initialization method for the class A
somewhere *inside* the class A?
-- Christoph
推荐答案
2006年3月1日星期三下午09:25:36 + 0100,Christoph Zwerschke写道:
On Wed, Mar 01, 2006 at 09:25:36PM +0100, Christoph Zwerschke wrote:
通常,你初始化类变量:
A类:
sum = 45
但是如果它们是某些计算或处理的结果,那么初始化类变量的正确方法是什么,如下面的愚蠢
示例(代表更多:
A类:
总和= 0
我在范围内(10):
总和+ =我
问题在于这使得任何辅助变量(如i)在这个愚蠢的例子中)也是类变量,这是不可取的。
当然,我可以调用类外部的函数
def calc_sum(n ):
......
A类:
sum = calc_sum(10)
但是我想知道是否可以把所有这个初始化代码转换为一个类初始化方法,类似于:
是的,它被称为元类。
类A:
@classmethod
def init_class(self):
sum = 0
我在范围内(10):
总和+ = i
自我。 sum = sum
init_class()
然而,这不起作用
Usually, you initialize class variables like that:
class A:
sum = 45
But what is the proper way to initialize class variables if they are the
result of some computation or processing as in the following silly
example (representative for more:
class A:
sum = 0
for i in range(10):
sum += i
The problem is that this makes any auxiliary variables (like "i" in this
silly example) also class variables, which is not desired.
Of course, I could call a function external to the class
def calc_sum(n):
...
class A:
sum = calc_sum(10)
But I wonder whether it is possible to put all this init code into one
class initialization method, something like that:
Yes, it is called a meta class.
class A:
@classmethod
def init_class(self):
sum = 0
for i in range(10):
sum += i
self.sum = sum
init_class()
However, this does not work
我们通常认为是实例是类的实例。
类实际上是元类的实例。你在找什么
是__init__,但不是在''A类'之后定义的__init__'''你想要
当你输入时调用__init__ 'A级......''
Python 2.4.1(#2,2005年3月30日,21:51:10)
[GCC 3.3 .5(Debian 1:3.3.5-8ubuntu2)] on linux2
输入help,copyright,credit等等。或许可证或更多信息。
What we normally think of as an instance is an instance of a class.
Classes are actually instances of metaclasses. What you are looking for
is __init__, but not the __init__ defined after ''class A...'' you want
the __init__ that is called when you type ''class A....''
Python 2.4.1 (#2, Mar 30 2005, 21:51:10)
[GCC 3.3.5 (Debian 1:3.3.5-8ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
class MyMeta(type):
.... def __init __(cls,* ignored) :
.... cls.sum = 0
.... for(i)in range(10):
.. .. cls.sum + = i
.... A类(对象):
.... __ metaclass__ = MyMeta
....打印A.sum
45打印Ai
Traceback(最近一次调用最后一次):
文件"< stdin>",第1行,在?
AttributeError:类型对象''''没有属性''我'
class MyMeta(type): .... def __init__(cls, *ignored):
.... cls.sum = 0
.... for (i) in range(10):
.... cls.sum += i
.... class A(object): .... __metaclass__ = MyMeta
.... print A.sum 45 print A.i Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: type object ''A'' has no attribute ''i''
对于像这样简单的东西例如,它更容易和更清洁
将循环移动到一个函数中并执行单行分配。
因为元类可以对类进行_anything_读者
有义务阅读其代码。来自
功能的简单分配显然没有副作用。
希望有所帮助,
-jackdied
For something as simple as this example it is easier and cleaner
to move the loop into a function and do the one-liner assignment.
Because the metaclass can do _anything_ to the class the reader
is obliged to go read its code. The simple assignment from a
function obviously has no side effects.
Hope that helps,
-jackdied
Christoph Zwerschke写道:
Christoph Zwerschke wrote:
通常,你初始化类变量:
A类:> sum = 45
但是如果它们是某些计算或处理的结果,那么初始化类变量的正确方法是什么,如下面的愚蠢
示例(代表更多:
A类:
总和= 0
我在范围内(10):
总和+ =我
问题是这使得任何辅助变量(如本例中的i愚蠢的例子)也是类变量,这是不可取的。
当然,我可以调用类外部的函数
def calc_sum(n):
...
A类:
sum = calc_sum(10)
但我想知道是否可以把所有这些都放进去将init代码转换成一个类初始化方法,类似于:
@classmethod
def init_class(self):
sum = 0
我在范围内(10):
sum + = i
self.sum = sum
init_class()
<但是,这不起作用,我得到
TypeError:''classmethod''对象不可调用
是否有另一种方法为A类放置初始化方法/>某处*里面* A级?
- Christoph
Usually, you initialize class variables like that:
class A:
sum = 45
But what is the proper way to initialize class variables if they are the
result of some computation or processing as in the following silly
example (representative for more:
class A:
sum = 0
for i in range(10):
sum += i
The problem is that this makes any auxiliary variables (like "i" in this
silly example) also class variables, which is not desired.
Of course, I could call a function external to the class
def calc_sum(n):
...
class A:
sum = calc_sum(10)
But I wonder whether it is possible to put all this init code into one
class initialization method, something like that:
class A:
@classmethod
def init_class(self):
sum = 0
for i in range(10):
sum += i
self.sum = sum
init_class()
However, this does not work, I get
TypeError: ''classmethod'' object is not callable
Is there another way to put an initialization method for the class A
somewhere *inside* the class A?
-- Christoph
虽然我从来没有需要这样的东西,
这个有效:
A级:
sum = 0
for i in range (10):
总和+ = i
del i
或将初始化移动到__init__方法是不是
非常低效,除非是在同一类中创建很多
个实例。
A类:
def __init __(自我):
self.sum = 0
for i in range(10):
self.sum + =我或你可以在实例化之前做到这一点
A类:
def __init __(self,initialvalue =无):
如果initialvalue不是None:self.sum = initialvalue
else:self.sum = 0
for i in range (10):
总和+ = i
b = A(总和)
c = A(总和)
-Larry Bates
Although I''ve never had the need for something like this,
this works:
class A:
sum=0
for i in range(10):
sum+=i
del i
or moving the initialization into __init__ method isn''t
terribly inefficient unless are are creating LOTS of
instances of the same class.
class A:
def __init__(self):
self.sum=0
for i in range(10):
self.sum+=i
or you can do the do it before you instantiate the class
class A:
def __init__(self, initialvalue=None):
if initialvalue is not None: self.sum=initialvalue
else: self.sum=0
for i in range(10):
sum+=i
b=A(sum)
c=A(sum)
-Larry Bates
Jack Diederich写道:
Jack Diederich wrote:
... __metaclass__ = MyMeta
... __metaclass__ = MyMeta
谢谢。我不知道__metaclass__属性。仍然有点
复杂,正如你所说,难以阅读,因为其他的解决方法已经提出了b $ b。无论如何,这可能不经常需要。
- Christoph
Thanks. I was not aware of the __metaclass__ attribute. Still a bit
complicated and as you said, difficult to read, as the other workarounds
already proposed. Anyway, this is probably not needed so often.
-- Christoph
这篇关于适当的类初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!