Python __插槽和未绑定方法

Python __插槽和未绑定方法,python,class,immutability,slots,Python,Class,Immutability,Slots,我需要一点关于插槽的帮助 class bstream(object): __slots__ = ['stream'] stream = string() def __new__(self, stream, encoding=None): if encoding == None: encoding = ENCODING['default'] if isinstance(stream, bytes): self.stream = stream.d

我需要一点关于插槽的帮助

class bstream(object):
  __slots__ = ['stream']
  stream = string()

  def __new__(self, stream, encoding=None):
    if encoding == None:
      encoding = ENCODING['default']
    if isinstance(stream, bytes):
      self.stream = stream.decode(encoding)
    elif isinstance(stream, string):
      self.stream = stream
    else: # if unknown type
      strtype = type(stream).__name__
      raise(TypeError('stream must be bytes or string, not %s' % strtype))
    return(self)

  def __repr__(self):
    '''bstream.__repr__() <==> repr(bstream)'''
    chars = ['\\x%s' % ('%02x' % ord(char)).upper() for char in self.stream]
    result = ''.join(chars)
    return(result)

  def func(self):
    return(1)
类B流(对象):
__时隙\uuux=['stream']
stream=string()
def _u新建(自、流、编码=无):
如果编码==无:
编码=编码['default']
如果isinstance(流,字节):
self.stream=stream.decode(编码)
elif isinstance(流、字符串):
self.stream=流
否则:#如果类型未知
strtype=类型(流)。\u\u名称__
raise(TypeError('流必须是字节或字符串,而不是%s“%strtype))
返回(自我)
定义报告(自我):
''b流._repr__()repr(b流)''
chars=['\\x%s%('%02x'%ord(char)).supper()表示self.stream中的char]
结果=“”。连接(字符)
返回(结果)
def func(自我):
报税表(1)
不要与字典中的字符串类型和编码混淆:它们是常量。 问题在于,以下命令无法按预期工作:

>>> var = bstream('data')
>>> repr(var)
<class '__main__.bstream'> # Instead of '\\x64\\x61\\x74\\x61'
>>> var.func()
TypeError: unbound method func() must be called with bstream instance as first argument (got nothing instead)
var=bstream('data')) >>>报告(var) #而不是“\\x64\\x61\\x74\\x61” >>>变量func() TypeError:必须以bstream实例作为第一个参数调用未绑定的方法func()(但没有得到任何结果)
怎么了?我真的想让我的类保持不变,因此删除插槽的解决方案实际上不是很好的解决方案。:-)非常感谢

您想使用
\uuuuu init\uuuuu
,而不是
\uuuu new\uuuuu

\uuuuu new\uuuuu
是一种类方法,其第一个参数(self)是类对象,而不是新创建的对象。它必须返回新对象。您通常不想重新定义它,但如果您想执行诸如返回现有对象之类的操作,您可以这样做

\uuuu init\uuuu
是一个常规实例方法,第一个参数(self)是新创建的实例。它与其他语言中的构造函数类似


要解决此问题,请将方法名称更改为
\uuuu init\uuu
,并删除最后一行(
返回(self)
)<代码>初始化。必须始终返回
None
;返回任何其他内容都会导致
类型错误

您希望使用
\uuuuu init\uuuuuuuuu
,而不是
\uuuu new\uuuuuuu

\uuuuu new\uuuuu
是一种类方法,其第一个参数(self)是类对象,而不是新创建的对象。它必须返回新对象。您通常不想重新定义它,但如果您想执行诸如返回现有对象之类的操作,您可以这样做

\uuuu init\uuuu
是一个常规实例方法,第一个参数(self)是新创建的实例。它与其他语言中的构造函数类似


要解决此问题,请将方法名称更改为
\uuuu init\uuu
,并删除最后一行(
返回(self)
)<代码>初始化。必须始终返回
None
;返回任何其他内容都会导致
类型错误

为什么<代码>\uuuuu插槽\uuuuu是相当无用的,尤其是在您知道需要它之前。这是一种使类不可变的糟糕方法,因此,不要对其进行变异(或者不要提供公共API来对其进行变异)。@Julian:你说得对,我定义它是为了使类不可变。以前,我总是使用Cython做同样的事情,但是它没有Python那么好的可移植性?如果你不想,就不要改变它。您在与Python对抗时非常努力。看看,您可能不想在这里使用
\uuuuuu slots\uuuuu
,我真的认为您也不想使用。@D.Shawley:它已经在Python 3中出现了。我之所以使用它,是因为当用户试图设置属性时,它仍然是避免错误的最佳方法。这也是减少Python处理对象时所需内存的一个好方法。为什么<代码>\uuuuu插槽\uuuuu是相当无用的,尤其是在您知道需要它之前。这是一种使类不可变的糟糕方法,因此,不要对其进行变异(或者不要提供公共API来对其进行变异)。@Julian:你说得对,我定义它是为了使类不可变。以前,我总是使用Cython做同样的事情,但是它没有Python那么好的可移植性?如果你不想,就不要改变它。您在与Python对抗时非常努力。看看,您可能不想在这里使用
\uuuuuu slots\uuuuu
,我真的认为您也不想使用。@D.Shawley:它已经在Python 3中出现了。我之所以使用它,是因为当用户试图设置属性时,它仍然是避免错误的最佳方法。这也是减少Python处理对象时所需内存的一个好方法。这会在创建对象时引发一个错误:
AttributeError:'bstream'对象属性'stream'是只读的
好的,我已经解决了:我只需要在
之后删除
stream=string()
。谢谢这在创建对象时引发了一个错误:
AttributeError:'bstream'对象属性'stream'是只读的
好的,我已经解决了它:我只需要在
之后删除
stream=string()
。谢谢