python中的int和str是什么意思_关于python:从str或int继承

为什么我在创建从str继承的类(或者从int继承的类)时遇到问题?

1

2

3

4

5

6

7

8class C(str):

def __init__(self, a, b):

str.__init__(self,a)

self.b = b

C("a","B")

TypeError: str() takes at most 1 argument (2 given)

如果我尝试使用int而不是str,也会发生同样的情况,但它适用于自定义类。我需要用__new__而不是__init__?为什么?

1

2

3

4

5

6

7

8

9

10>>> class C(str):

... def __new__(cls, *args, **kw):

... return str.__new__(cls, *args, **kw)

...

>>> c = C("hello world")

>>> type(c)

>>> c.__class__.__mro__

(, , , )

由于在构造对象之后调用__init__,因此修改不可变类型的值为时已晚。注意,__new__是一个类方法,所以我调用了第一个参数cls。

有关详细信息,请参阅此处

1

2

3

4

5

6

7

8

9

10

11>>> class C(str):

... def __new__(cls, value, meta):

... obj = str.__new__(cls, value)

... obj.meta = meta

... return obj

...

>>> c = C("hello world","meta")

>>> c

'hello world'

>>> c.meta

'meta'

我用我自己的答案,帮助你操作系统的问题的答案在这里。好的,谢谢!

继承内置类型是非常不值得的。你必须处理好几个问题,但实际上你得不到多少好处。

使用构图几乎总是更好的。您将保留一个str对象作为属性,而不是继承str。

1

2

3class EnhancedString(object):

def __init__(self, *args, **kwargs):

self.s = str(*args, **kwargs)

您可以推迟任何您想在基础strself.s上使用的方法,手动或自动使用__getattr__。

也就是说,需要自己的字符串类型应该会让你暂停。有许多类应该存储一个字符串作为它们的主数据,但是您通常希望使用str或unicode(如果您表示文本,则后者)来表示字符串的一般表示。(一个常见的例外是,如果需要使用UI工具箱的字符串类型。)如果要向字符串中添加功能,请尝试使用对字符串而不是新对象操作的函数作为字符串,这样可以使代码更简单,更与其他人的程序兼容。

是的,这是我的第一个解决方案,但我有一个问题是,一些函数的字符串参数是想要(他们是从C + +函数库,I can’t修改)操作系统实现这些函数的使用与我的工作我的类的参数。你可以得到更好的解释这一结果__getattr__如何使用?

"接受维速,一个参数是一个字符串underdefined的事。我不知道你是什么样的C + +库和它是如何包装的包裹,但应该做的正确的类型的兼容工作。制作你自己的新类中所看到的那一个人,而不是利用它在Python的字符串或字符串的类的类(和它看起来像这样的工作)的工作方式,使奇异的事情。

"明智的,使用未定义的属性__getattr__推迟到其他特定的属性的组合是一对在accomplished样def __getattr__(self, name): return getattr(self.s, name))代码。请注意,此代码是不是好的建议,一定可以解决,但在一些情况下,它的更好的东西,往往要到你手动设置在组合。

我有一个c_function(char*),我可以使用它在Python中的c_function(s)s是str实例。S代表的东西,和我想要的,这有beautiful_namename,在线等。我有一个来自strC衍生类,所以我可以通一到C对象的类,例如的Cpython_functionprint c.name和呼叫c_function(c)

"inheriting >内置类型,是非常不值得。"这可能是真实的,但不总是。有时它是有用的创建省级"标记字符串"类型,如不同类型的字符串产生的令牌从一类的解析器。然而,与它的问题,那是你的(我认为)在短柱的性能优化。

@案例中,Blais,组合仍然是不多的,易错的。从strinheriting是潜在的误差源,但不是真的帮助你。

我不convinced。为什么你认为你能指出潜在的inheriting源从STR是错误的吗?因为它不是idiomatic吗?

docs.python.org / 3 /图书馆/ & hellip;"类的行为,userstring包装周围的字符串对象。需要为这个类已经由局部supplanted能力直接从乙方的子类;"这并不是说不。

"你的suppose Blais,your_subclass[:5]或your_subclass.replace(x, y)-什么回报吗?一个实例的实例的子类或一str你吗?即使这是不是确定的,但在实践中,它将返回str。有没有保证,任何方式,这是未定义行为的排序(坏的东西。

"你应该总是Blais,写的代码是可能的和平的不了解什么是可能的。是一个简单的内置程序,很难想起的,持久的,和使用。

当实例化一个类时,传入的参数将同时传递给该类的__new__方法和__init__方法。因此,如果您继承的类对实例化期间可能提供的参数数量有限制,则必须保证其__new__和__init__都不会得到比预期更多的参数。所以这就是你的问题所在。用C("a","B")实例化类。解释器在C中查找__new__方法。C没有它,所以python窥视它的基类str。因为它有一个,所以使用和提供两个参数。但是str.__new__只期望得到一个参数(除了作为第一个参数的类对象之外)。所以提出了TypeError。这就是为什么你必须在你的孩子班上扩展它,类似于你对__init__所做的。但是要记住,如果使用super函数,它必须返回类实例,并且它是一个静态方法(不管它是否用@staticmethoddecorator定义)。

要验证,请在提示下尝试:>>> str.__init__('abc', 'def')。这没用。但是,>>> str.__new__(str, 'abc', 'def')抛出了例外:TypeError: str() takes at most 1 argument (2 given)。这有点让人困惑,因为我们称str.__new__(..)为3个参数,而不是2个参数。这是否意味着str.__new__(..)接受任何数量的参数,然后调用str(..)?可能不会,因为str(..)会依次调用str.__new__(..)。

@evgeni:str类对象根本不实现__init__方法。basestring也不是(str的基类)。__init__直接从object继承而来,并且该继承人接受任何数量的论据。相反,__new__方法实际上是在str中实现的,除了第一个必须是str或其子类的参数外,它最多接受1个参数。用__new__、basestring、object等表达。

这是检查实现哪些方法的好方法。我还是有点困惑为什么我要写str.__new__(str, 'abc', 'def'),它说我提供了2个参数。我数到三。例如class C(object):

@staticmethod

def m(a): pass,如果我把它叫做C.m(1, 2),它会像预期的那样说TypeError: m() takes exactly 1 argument (2 given)。我猜__new__产生了一个混乱的消息,因为__new__是特殊的(例如,在实现它时不需要添加@staticmethod)。

对于不可变类型,使用__new__:

1

2

3

4

5

6

7

8

9class C(str):

def __new__(cls, content, b):

return str.__new__(cls, content)

def __str__(self):

return str.__str__(self)

a=C("hello","world")

print a

print返回hello。

python字符串是不可变的类型。调用函数__new__来创建对象C的新实例。python __new__函数的基本存在是为了允许从不可变类型继承。

type(C("a","B"))→NoneType

你试试你的答案吗?现在它的回报"

1?至少你可以写评论吗?

2我写的评论。

你的检查和更新的帖子?根据你的要求,这是最新的。你倒是voted后的变化。此外,在你的评论,你会从我的代码功能,这是不要求的问题(让你_ _ str()函数_ _工作在继承的类)。

在第一次执行代码后的第二NoneType归国后,""它了。它不要求功能吗?I didn’t ask a __str__函数和它是不必要的,因为从类继承的str,国有企业gnibbler回答。现在我不能修改的downvote,i需要你编辑你的答案。

仔细阅读之后,这里还有另一种尝试,试图对str进行子类化。与其他答案不同的是,使用super(TitleText, cls).__new__在正确的类中创建实例。这个函数在使用时的行为看起来像str,但允许我重写一个方法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19class TitleText(str):

title_text=""

def __new__(cls,content,title_text):

o=super(TitleText, cls).__new__(cls,content)

o.title_text = title_text

return o

def title(self):

return self.title_text

>>> a=TitleText('name','A nice name')

>>> a

'name'

>>> a[0]

'n'

>>> a[0:2]

'na'

>>> a.title()

'A nice name'

这样可以正确地进行切片和订阅。这是干什么的?用于重命名管理索引页中的Django应用程序。

讨厌!您的repr是欺骗性的,这一事实导致我们不清楚,虽然a是TitleText,但a[0]和a[0:2]是str(现在,在当前版本中,作为实现细节)。如果您编写了一个没有继承str的类,那么您可以使一个更有用、更不容易混淆和欺骗的东西。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值