Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中对str进行子类化_Python_Subclassing_Fluent Interface - Fatal编程技术网

如何在Python中对str进行子类化

如何在Python中对str进行子类化,python,subclassing,fluent-interface,Python,Subclassing,Fluent Interface,我正在尝试对str对象进行子类化,并向其添加两个方法。我的主要目的是学习如何做。我陷入困境的地方是,我应该在一个元类中对string进行子类化,然后用那个元类创建我的类,还是直接用子类str创建我的类 另外,我想我需要以某种方式实现\uuuuuu new\uuuuu(),因为我的自定义方法将修改我的string对象,并返回新的mystr obj 我的类的方法应该可以与str方法完全链接,并且当自定义方法修改它时,应该始终返回一个新的我的类实例。我希望能够做到以下几点: a = mystr("so

我正在尝试对str对象进行子类化,并向其添加两个方法。我的主要目的是学习如何做。我陷入困境的地方是,我应该在一个元类中对string进行子类化,然后用那个元类创建我的类,还是直接用子类str创建我的类

另外,我想我需要以某种方式实现
\uuuuuu new\uuuuu()
,因为我的自定义方法将修改我的string对象,并返回新的mystr obj

我的类的方法应该可以与str方法完全链接,并且当自定义方法修改它时,应该始终返回一个新的我的类实例。我希望能够做到以下几点:

a = mystr("something")
b = a.lower().mycustommethod().myothercustommethod().capitalize()
issubclass(b,mystr) # True
a = mystr("something")
b = a.lower().mycustommethod().myothercustommethod().capitalize()
issubclass(b,mystr) # True
我想拥有
str
拥有的所有能力。例如,
a=mystr(“某物”)
然后我想像这样使用它, a、 大写().mycustommethod().lower()

我的理解是,我需要实现
\uuuu new\uuuu()
。我这样认为是因为strings方法可能会尝试创建新的str实例。因此,如果我覆盖
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。但是,在这种情况下,我不知道如何将参数传递给自定义类的
\uuu init\uu()
方法。我想我需要使用
type()
\uuuuuuuuuuuuuuuuuuuu()
方法中创建一个新实例,对吗?

如果您想在构造时修改字符串,覆盖
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

class caps(str):
   def __new__(cls, content):
      return str.__new__(cls, content.upper())
但是,如果您只想添加新方法,您甚至不必接触构造函数:

class text(str):
   def duplicate(self):
      return text(self + self)

请注意,继承的方法,例如
upper()
仍将返回正常的
str
,而不是
text

,您可以尝试以下操作:

class mystr(str):
    def new_method(self):
        pass

但是您不能确定标准方法是否也会返回“mystr”实例,这里有一个快速的方法可以实现您的目的:基本上拦截每个函数调用,如果您看到它返回字符串,您可以将其转换回您自己的类类型

虽然这在这个简单的示例中有效,但它有一些局限性。除此之外,诸如下标运算符之类的运算符显然没有得到处理

class FunWrapper(object):
    def __init__(self, attr):
        self.attr = attr

    def __call__(self, *params, **args):
        ret = self.attr(*params, **args)
        if type(ret) is str:
            return Foo(ret)
        return ret

class Foo(object):
    def __init__(self, string):
        self.string = string

    def __getattr__(self, attr):
        return FunWrapper(getattr(self.string, attr))

    def newMethod(self):
        return "*%s*" % self.string.upper()


f = Foo('hello')
print f.upper().newMethod().lower()
我正在尝试对str对象进行子类化,并向其添加两个方法。我的主要目的是学习如何做。
UserString
是在可以直接对
str
进行子类化之前创建的,因此更倾向于将
str
子类化,而不是使用
UserString
(另一个答案建议)

当对不可变对象进行子类化时,通常需要在实例化对象之前修改数据——因此,您需要实现
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,并调用父对象
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

在Python 3中,像这样调用
super
更有效:

a = mystr("something")
b = a.lower().mycustommethod().myothercustommethod().capitalize()
issubclass(b,mystr) # True
a = mystr("something")
b = a.lower().mycustommethod().myothercustommethod().capitalize()
issubclass(b,mystr) # True
class Caps(str):
定义新内容(cls,内容):
返回super()
\uuuu new\uuuu
看起来像一个类方法,但实际上它是作为一个静态方法实现的,因此我们需要冗余地传递
cls
作为第一个参数。然而,我们不需要
@staticmethod
装饰器

如果我们像这样使用
super
来支持Python 2,我们将更清楚地注意到冗余的
cls

class Caps(str):
定义新内容(cls,内容):
返回super(Caps,cls)。\uuuu new\uuuu(cls,content.upper())
用法:

>Caps('foo')
“福”
>>>iInstance(大写('foo'),大写)
真的
>>>isinstance(大写('foo'),str)
真的
完整答案 到目前为止,没有一个答案符合您的要求:

我的类的方法应该可以完全链接到str方法, 并且在自定义方法时应始终返回一个新的my class实例 修改了它。我希望能够做到以下几点:

a = mystr("something")
b = a.lower().mycustommethod().myothercustommethod().capitalize()
issubclass(b,mystr) # True
a = mystr("something")
b = a.lower().mycustommethod().myothercustommethod().capitalize()
issubclass(b,mystr) # True
(我相信你的意思是
isinstance()
,而不是
issubclass()

您需要一种截取字符串方法的方法<代码>\uuuu getattribute\uuuuu
不执行此操作

现在:

>>> a = Caps("something")
>>> a.lower()
Caps('SOMETHING')
>>> a.casefold()
Caps('SOMETHING')
>>> a.swapcase()
Caps('SOMETHING')
>>> a.index('T')
4
>>> a.strip().split('E')
[Caps('SOM'), Caps('THING')]
本案所要求的工作:

>>> a.lower().mycustommethod().myothercustommethod().capitalize()
Caps('SOMETHING!!!')
对评论的回应 为什么Python3的唯一调用,即super().method(arg)性能更好

该函数已经可以访问
\uuuu class\uuu
self
,而无需执行全局和本地查找:

课堂演示:
def foo(self):
打印(局部变量())
打印(类)
>>>Demo().foo()
{'self':,'uuuuuuuuuuu类:}

有关更多信息,请参阅。

我对其他答案的复杂性感到震惊,python标准库也是如此。您可以使用来对字符串进行子类化,并且不会干扰代理
str
的方法

只需将其子类化,并添加您的方法
self.data
包含由对象表示的实际字符串,因此您甚至可以通过在内部重新分配
self.data
来实现str-“mutating”方法


.

@yasar11732:sth在下面指出,
a.capitalize()
将返回一个标准的、未修改的
str
,而不是您的自定义类,因此
a.capitalize().mycustommethod()
将失败。编写两个函数并直接执行
mycustommethod(a.capitalize()).lower()
,这是一种非常非常好的编码实践,因为这不会让其他阅读您代码的人感到困惑(顺便说一句,“其他人”包括“您,两年后”)。更通用的方法是基于uu init_uu(self,*args,**kwargs)+super()正在报告弃用警告:对象。\uuuu init\uuuu()不接受任何参数。因此,我认为uuu new_uuuu(cls,*args,**kwargs)是一种更好的方法。或也许这解释得更好:另请参见:
six.moves UserString
“但是UserString不是str的子类,因此如果需要进行即时检查,这不是一个选项。回答不错+1。不是json可序列化的tho。另外,重写
\u str\uuuuuuuuu()
也是值得一提的,因为作为值访问
self