不可变实例,常数值 [英] Immutable instances, constant values

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

问题描述

Howdy all,


我最近在PyPI中打包了'enum'。在其描述中,我将

声明创建为不可变的声明。枚举对象,并且

枚举值是常量的。价格。


这引发了一些问题。


Python不可变值与

之间有什么区别吗?不变?我认为不变也暗示* name *不可变地将某个值绑定到特定值。这有意义吗?


如何确保对象是不可变的?这是一个覆盖一堆方法的问题吗?或者是一种更简洁的方法吗?


制作用户定义的类是不好的风格创建不可变的

对象?为什么?


对于'enum'',任何人都可以争论或反对枚举的

类型是不可变的吗?它的价值是不变的?


-

\最好的广告词是排练的。 - Graham Kennedy |
` \ |

_o__)|

Ben Finney

Howdy all,

I''ve recently packaged ''enum'' in PyPI. In its description, I make the
claim that it creates "immutable" enumeration objects, and that the
enumeration values are "constant" values.

This raises questions.

Is there any difference between a Python immutable value, and a
constant? I suppose "constant" also implies that the *name* binds
unchangeably to a particular value. Is that meaningful?

How does one actually ensure an object is immutable? Is it a matter of
overriding a bunch of methods, or is ther a neater way?

Is it bad style to make a user-defined class that creates immutable
objects? Why?

In the case of ''enum'', can anyone argue for or against an enumerated
type being immutable? Its values being constant?

--
\ "The best ad-libs are rehearsed." -- Graham Kennedy |
`\ |
_o__) |
Ben Finney

推荐答案

2005年11月18日星期五14:32:46 +1100(美国东部时间),Ben Finney< bi **************** @ benfinney。 id.au>写道:
On Fri, 18 Nov 2005 14:32:46 +1100 (EST), Ben Finney <bi****************@benfinney.id.au> wrote:
你好,

我最近在PyPI中打包了''enum''。在其描述中,我声称它创建了不可变的声明。枚举对象,并且
枚举值是常量的。值得提出。

这引发了一些问题。

Python不可变值和
常量之间有什么区别吗?我认为不变也暗示* name *不可变地绑定到特定值。这有意义吗?

如何确保对象是不可变的?是一个覆盖一堆方法的问题,还是一个更简洁的方法?

创建一个用户定义的类创建不可变的对象是不好的风格?为什么?

对于'enum'',任何人都可以争论或反对枚举的
类型是不可变的吗?它的值是不变的?
Howdy all,

I''ve recently packaged ''enum'' in PyPI. In its description, I make the
claim that it creates "immutable" enumeration objects, and that the
enumeration values are "constant" values.

This raises questions.

Is there any difference between a Python immutable value, and a
constant? I suppose "constant" also implies that the *name* binds
unchangeably to a particular value. Is that meaningful?

How does one actually ensure an object is immutable? Is it a matter of
overriding a bunch of methods, or is ther a neater way?

Is it bad style to make a user-defined class that creates immutable
objects? Why?

In the case of ''enum'', can anyone argue for or against an enumerated
type being immutable? Its values being constant?



我的enum概念来自(我记得的)Pascal,它是

基本上是一组有序的整数形成的名字一个类型,并且

ord(one_of_the_names)获取索引值。 Python的ord似乎需要一个长度为1的字符串,并且似乎没有尝试强制,

因此如果没有mod,它可能无法飞行。


但是我们所拥有的是整数,就像True和False一样构建在
名称中的整数子类型值为1和0。所以我会说枚举应该

也是int子类型...


无论如何,我希望name-> ord(name)映射是不可变的

一旦定义(虽然不一定会痴迷于阻止因果终结)。

Hm,也许更具体......


My notion of enum comes from (what I remember of) Pascal, which is
basically an ordered set of names of integers forming a type, and
ord(one_of_the_names) gets you the index value. Python''s ord seems
to demand a string of length one, and doesn''t seem to attempt coercion,
so that might not fly without a mod.

But what we have is named integers, much as True and False are built in
names for integer subtypes with value 1 and 0. So I''d say enums should
also be int subtypes...

Anyway, I would hope that the name->ord(name) mapping would be immutable
once defined (though not necessarily obsessively preventing the ususal end runs).
Hm, might as well be more concrete ...

def makeEnum(ename,names):
... names = names.split()

.. .top = len(名字)

... #define方法在类外面的函数所以它们将是闭包访问嵌套名称

... def __new __(cls, name = names [0]):

...尝试:

... i = names.index(name)

... return int .__ new __(cls,i)

...除了ValueError:

... if isinstance(name,int)和0<名称< top:return int .__ new __(cls,name)

... raise ValueError,''非法%s枚举值%r''%(cls .__ name__,name)

... def __repr __(self):return''%s(%s)''%(self .__ class __.__ name __,name [self])

...#return names with class或实例的name属性

... class getnames(object):

... def __set __(* ignore):引发AttributeError,''names protected''

... getnames .__ get__ = lambda * ignore:names [:]

...返回类型(ename,(int,),{''__ new__'' :__ new __,'_ _ _ _ _ _ _'':__ repr __,'_ _ _ _ _ _ _ _'':__ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ..

...颜色= makeEnum(''颜色'',''红绿蓝'')颜色
< class''__ main __。颜色'' >颜色()
颜色(红色)颜色(1)
颜色(绿色)r,g,b =(Colors.names中名称的颜色(名称))
r
颜色(红色)g
颜色(绿色)b
颜色(蓝色)''ABC''[g]
''B''int(g)
1颜色( 5)
回溯(最近一次调用最后一次):

文件"< stdin>",第1行,在?

文件"< stdin>",第11行,在__new__

ValueError:非法颜色枚举值5颜色(''''')
颜色(蓝色)颜色(2)
颜色(蓝色)颜色(''orange'')
回溯(最近一次调用最后一次):

文件"< stdin>",第1行,在?

文件"< stdin>",第11行,__ new__

ValueError:非法彩色枚举值''orange''


只是一些想法。

哦,名字有点受[:]保护,但如果你试图改变,真的应该抛出

例外。

Colors.names
[''red'',''green'',''blue''] Colors.names [2]
''blue''Colors.names [2] =''indigo''
Colors.names [2]
def makeEnum(ename, names): ... names = names.split()
... top = len(names)
... # define method functions outside class so they''ll be closures accessing nested names
... def __new__(cls, name=names[0]):
... try:
... i = names.index(name)
... return int.__new__(cls, i)
... except ValueError:
... if isinstance(name, int) and 0< name < top: return int.__new__(cls, name)
... raise ValueError, ''illegal %s enum value %r''%(cls.__name__, name)
... def __repr__(self): return ''%s(%s)'' %(self.__class__.__name__, names[self])
... # return names with names attribute of class or instance
... class getnames(object):
... def __set__(*ignore): raise AttributeError, ''names protected''
... getnames.__get__ = lambda *ignore: names[:]
... return type(ename, (int,),{''__new__'':__new__, ''__repr__'':__repr__, ''__str__'':__repr__,
... ''names'':getnames()})
...
... Colors = makeEnum(''Color'', ''red green blue'')
Colors <class ''__main__.Color''> Colors() Color(red) Colors(1) Color(green) r,g,b = (Colors(name) for name in Colors.names)
r Color(red) g Color(green) b Color(blue) ''ABC''[g] ''B'' int(g) 1 Colors(5) Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 11, in __new__
ValueError: illegal Color enum value 5 Colors(''blue'') Color(blue) Colors(2) Color(blue) Colors(''orange'') Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 11, in __new__
ValueError: illegal Color enum value ''orange''

Just some thoughts.
Oh, names are kind of protected by [:], but really should throw
an exception if you try to mutate.
Colors.names [''red'', ''green'', ''blue''] Colors.names[2] ''blue'' Colors.names[2] = ''indigo''
Colors.names[2]



''蓝色''


返回一个元组会很容易。

保护起来并不容易对于Colors.names =的东西

因为__metaclass__跳过工厂本地的全局而不是在类范围内,

并传递一个''__metaclass__'':mcdefinition在dict arg中类型确实

不会导致调用,它只会成为另一个被动类变量。

必须是一种方式。现在太累了...


问候,

Bengt Richter


''blue''

It would be easy to return a tuple.
It''s not that easy to protect against Colors.names = something
since __metaclass__ skips factory local to global if not in class scope,
and passing a ''__metaclass__'': mcdefinition in the dict arg to type does
not result in a call, it just becomes another passive class variable.
Must be a way though. Too tired for now...

Regards,
Bengt Richter


周五,18 2005年11月14:32:46 +1100(美国东部时间),Ben Finney< bi **************** @ benfinney.id.au>写道:
On Fri, 18 Nov 2005 14:32:46 +1100 (EST), Ben Finney <bi****************@benfinney.id.au> wrote:
你好,

我最近在PyPI中打包了''enum''。在其描述中,我声称它创建了不可变的声明。枚举对象,并且
枚举值是常量的。值得提出。

这引发了一些问题。

Python不可变值和
常量之间有什么区别吗?我认为不变也暗示* name *不可变地绑定到特定值。这有意义吗?

如何确保对象是不可变的?是一个覆盖一堆方法的问题,还是一个更简洁的方法?

创建一个用户定义的类创建不可变的对象是不好的风格?为什么?

对于'enum'',任何人都可以争论或反对枚举的
类型是不可变的吗?它的值是不变的?
Howdy all,

I''ve recently packaged ''enum'' in PyPI. In its description, I make the
claim that it creates "immutable" enumeration objects, and that the
enumeration values are "constant" values.

This raises questions.

Is there any difference between a Python immutable value, and a
constant? I suppose "constant" also implies that the *name* binds
unchangeably to a particular value. Is that meaningful?

How does one actually ensure an object is immutable? Is it a matter of
overriding a bunch of methods, or is ther a neater way?

Is it bad style to make a user-defined class that creates immutable
objects? Why?

In the case of ''enum'', can anyone argue for or against an enumerated
type being immutable? Its values being constant?



我的enum概念来自(我记得的)Pascal,它是

基本上是一组有序的整数形成的名字一个类型,并且

ord(one_of_the_names)获取索引值。 Python的ord似乎需要一个长度为1的字符串,并且似乎没有尝试强制,

因此如果没有mod,它可能无法飞行。


但是我们所拥有的是整数,就像True和False一样构建在
名称中的整数子类型值为1和0。所以我会说枚举应该

也是int子类型...


无论如何,我希望name-> ord(name)映射是不可变的

一旦定义(虽然不一定会痴迷于阻止因果终结)。

Hm,也许更具体......


My notion of enum comes from (what I remember of) Pascal, which is
basically an ordered set of names of integers forming a type, and
ord(one_of_the_names) gets you the index value. Python''s ord seems
to demand a string of length one, and doesn''t seem to attempt coercion,
so that might not fly without a mod.

But what we have is named integers, much as True and False are built in
names for integer subtypes with value 1 and 0. So I''d say enums should
also be int subtypes...

Anyway, I would hope that the name->ord(name) mapping would be immutable
once defined (though not necessarily obsessively preventing the ususal end runs).
Hm, might as well be more concrete ...

def makeEnum(ename,names):
... names = names.split()

.. .top = len(名字)

... #define方法在类外面的函数所以它们将是闭包访问嵌套名称

... def __new __(cls, name = names [0]):

...尝试:

... i = names.index(name)

... return int .__ new __(cls,i)

...除了ValueError:

... if isinstance(name,int)和0<名称< top:return int .__ new __(cls,name)

... raise ValueError,''非法%s枚举值%r''%(cls .__ name__,name)

... def __repr __(self):return''%s(%s)''%(self .__ class __.__ name __,name [self])

...#return names with class或实例的name属性

... class getnames(object):

... def __set __(* ignore):引发AttributeError,''names protected''

... getnames .__ get__ = lambda * ignore:names [:]

...返回类型(ename,(int,),{''__ new__'' :__ new __,'_ _ _ _ _ _ _'':__ repr __,'_ _ _ _ _ _ _ _'':__ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ..

...颜色= makeEnum(''颜色'',''红绿蓝'')颜色
< class''__ main __。颜色'' >颜色()
颜色(红色)颜色(1)
颜色(绿色)r,g,b =(Colors.names中名称的颜色(名称))
r
颜色(红色)g
颜色(绿色)b
颜色(蓝色)''ABC''[g]
''B''int(g)
1颜色( 5)
回溯(最近一次调用最后一次):

文件"< stdin>",第1行,在?

文件"< stdin>",第11行,在__new__

ValueError:非法颜色枚举值5颜色(''''')
颜色(蓝色)颜色(2)
颜色(蓝色)颜色(''orange'')
回溯(最近一次调用最后一次):

文件"< stdin>",第1行,在?

文件"< stdin>",第11行,__ new__

ValueError:非法彩色枚举值''orange''


只是一些想法。

哦,名字有点受[:]保护,但如果你试图改变,真的应该抛出

例外。

Colors.names
[''red'',''green'',''blue''] Colors.names [2]
''blue''Colors.names [2] =''indigo''
Colors.names [2]
def makeEnum(ename, names): ... names = names.split()
... top = len(names)
... # define method functions outside class so they''ll be closures accessing nested names
... def __new__(cls, name=names[0]):
... try:
... i = names.index(name)
... return int.__new__(cls, i)
... except ValueError:
... if isinstance(name, int) and 0< name < top: return int.__new__(cls, name)
... raise ValueError, ''illegal %s enum value %r''%(cls.__name__, name)
... def __repr__(self): return ''%s(%s)'' %(self.__class__.__name__, names[self])
... # return names with names attribute of class or instance
... class getnames(object):
... def __set__(*ignore): raise AttributeError, ''names protected''
... getnames.__get__ = lambda *ignore: names[:]
... return type(ename, (int,),{''__new__'':__new__, ''__repr__'':__repr__, ''__str__'':__repr__,
... ''names'':getnames()})
...
... Colors = makeEnum(''Color'', ''red green blue'')
Colors <class ''__main__.Color''> Colors() Color(red) Colors(1) Color(green) r,g,b = (Colors(name) for name in Colors.names)
r Color(red) g Color(green) b Color(blue) ''ABC''[g] ''B'' int(g) 1 Colors(5) Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 11, in __new__
ValueError: illegal Color enum value 5 Colors(''blue'') Color(blue) Colors(2) Color(blue) Colors(''orange'') Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 11, in __new__
ValueError: illegal Color enum value ''orange''

Just some thoughts.
Oh, names are kind of protected by [:], but really should throw
an exception if you try to mutate.
Colors.names [''red'', ''green'', ''blue''] Colors.names[2] ''blue'' Colors.names[2] = ''indigo''
Colors.names[2]



''蓝色''


返回一个元组会很容易。

保护起来并不容易对于Colors.names =的东西

因为__metaclass__跳过工厂本地的全局而不是在类范围内,

并传递一个''__metaclass__'':mcdefinition在dict arg中类型确实

不会导致调用,它只会成为另一个被动类变量。

必须是一种方式。现在太累了...


问候,

Bengt Richter


''blue''

It would be easy to return a tuple.
It''s not that easy to protect against Colors.names = something
since __metaclass__ skips factory local to global if not in class scope,
and passing a ''__metaclass__'': mcdefinition in the dict arg to type does
not result in a call, it just becomes another passive class variable.
Must be a way though. Too tired for now...

Regards,
Bengt Richter


Bengt Richter< bo**@oz.net>写道:
Bengt Richter <bo**@oz.net> wrote:
Ben Finney< bi **************** @ benfinney.id.au>写道:
Ben Finney <bi****************@benfinney.id.au> wrote:
我最近在PyPI中打包了''枚举''。 [...]
我的enum概念来自(我记得的)Pascal
I''ve recently packaged ''enum'' in PyPI. [...]
My notion of enum comes from (what I remember of) Pascal




您可能想调查''enum''包我的想法是如何使用

枚举类型。

这基本上是形成
类型的整数名称的有序集合,以及ord(one_of_the_names)获取索引值。


获取数字索引可能对Pascal等语言很有用,
没有内置字典或序列类型。在Python中,任何

不可变对象都可以是一个dict键,任何序列都可以迭代,

似乎没用。

但是我们所拥有的是整数,就像在整数子类型的名称中建立值为1和0的True和False一样。


这是一个实现细节;肯定代码不应该期望

整数和布尔值之间的任何特定关系吗?

所以我会说枚举也应该是int子类型...



You might want to investigate the ''enum'' package for my idea of how an
enumerated type can work.
which is basically an ordered set of names of integers forming a
type, and ord(one_of_the_names) gets you the index value.
Getting a numeric index might be useful in a language such as Pascal,
with no built-in dict or sequence types. In Python, where any
immutable object can be a dict key, and any sequence can be iterated,
it seems of no use.
But what we have is named integers, much as True and False are built
in names for integer subtypes with value 1 and 0.
That''s an implementation detail; surely code shouldn''t be expecting
any particular relationship between integers and boolean values?
So I''d say enums should also be int subtypes...




同样,这似乎最好留作实现细节。为什么期望

任何特定的映射到int值?对枚举值执行算术或布尔值

逻辑似乎违背了它们的目的。


-

\我们倾向于嘲笑古人的信仰。但是,我们不能对他们个人,他们的脸嗤之以鼻,这就是让我感到烦恼的事情。&bbspre:b $ $ $))))))))))))))))))))))) - Jack Handey |

Ben Finney



Likewise, that seems best left as an implementation detail. Why expect
any particular mapping to int values? Doing arithmetic or boolean
logic on enumerated values seems against their purpose.

--
\ "We tend to scoff at the beliefs of the ancients. But we can''t |
`\ scoff at them personally, to their faces, and this is what |
_o__) annoys me." -- Jack Handey |
Ben Finney


这篇关于不可变实例,常数值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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