首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当调用字符串的子类时,将参数绑定到__init__的两个参数?

当调用字符串的子类时,将参数绑定到__init__的两个参数?
EN

Stack Overflow用户
提问于 2015-05-21 09:31:50
回答 3查看 92关注 0票数 1

在Python2.7中,当以字符串作为参数运行时,下面的类语句似乎将该字符串绑定到init ('self‘和’蚱蜢‘)的两个参数。

方法可以定义为在self和self.grasshopper上以看似相同的结果操作。

我注意到,如果init被定义为接受三个参数--例如'self‘、’蚱蜢‘和'beetle’--类在运行时使用两个字符串参数(例如,CrazyString(“垃圾邮件”,“鸡蛋”)),则会引发错误:

代码语言:javascript
复制
TypeError: str() takes at most 1 argument (2 given)

这表明'str‘不仅仅是由类CrazyString继承的,而是作为一个函数执行的。

我不明白正在发生什么,因此我不确定我是应该编写在self上操作的方法还是在self.grasshopper上操作。还是self和self.grasshopper实际上是一样的?

代码语言:javascript
复制
class CrazyString(str):

    def __init__(self, grasshopper):
        self.grasshopper = grasshopper

    def backwards1(self):
        return self.grasshopper[::-1]

    def backwards2(self):
        return self[::-1]

if __name__ == "__main__":
    cs = CrazyString('spam')
    print cs
    print cs.grasshopper
    print cs.backwards1()
    print cs.backwards2()

当运行('python crazy.py')时,我得到以下输出:

代码语言:javascript
复制
spam
spam
maps
maps
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-21 09:41:32

这个答案有两个部分:解释str初始化在哪里进行(因为您不调用str.__init__),以及解释“str在哪里存储字符串”。

首先,由于str是用C实现的不可变类型,所以str.__init__实际上并不涉及初始化字符串。还有另一种方法,__new__,在__init__初始化它们之前调用它来创建一个类型的实例,对于str这样的不可变类型,__new__会创建预先初始化的对象。(毕竟,如果__init__初始化了字符串,那将是一个突变。)

其次,self看起来是一个字符串,因为它应该是一个字符串。您是从str继承的,所以类的实例是str的实例;它们是字符串!您可以像字符串一样print它们,也可以像字符串和所有东西一样将它们反转,因为它们继承了str中的所有内容。您不需要使用类似于self.str的东西“获取底层字符串”,就像人们有时所期望的那样。

票数 2
EN

Stack Overflow用户

发布于 2015-05-21 09:49:53

在您的例子中,您在__new__函数上绊倒了,这给您带来了麻烦。

你应该做(未经测试的!)

代码语言:javascript
复制
class CrazyString(str):

    def __new__(cls, grasshopper, beetle):
        return cls(grasshopper) # not sure if that works, maybe we have to use super() in any way...

    def __init__(self, grasshopper, beetle):
        self.grasshopper = grasshopper
        self.beetle = grasshopper

    def backwards1(self):
        return self.grasshopper[::-1]

    def backwards2(self):
        return self[::-1]

    def backwards3(self):
        return self.beetle[::-1]

if __name__ == "__main__":
    cs = CrazyString('spam')
    print cs
    print cs.grasshopper
    print cs.backwards1()
    print cs.backwards2()
    print cs.backwards3()
票数 0
EN

Stack Overflow用户

发布于 2015-05-21 10:56:15

因此,__new__方法在将字符串“垃圾邮件”作为第二个参数传递给__init__之前,就会将其转换为'str‘类型的对象。

如果有一个__init__具有任意数量的参数,但只有两个参数,那么调用CrazyString('spam')将失败,并使用TypeError退出。这样做是可行的:

代码语言:javascript
复制
class CrazyString(str):
    def backwards(self):
        return self[::-1]

if __name__ == "__main__":
    cs = CrazyString('spam')
    print cs
    print cs.backwards()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30369837

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档