skyteam超级吕布 发表于 2024-7-20 09:49:20

类和对象__new__()

小甲鱼的第65讲有个“__new__()”的魔法方法,可以改变不可变的数据类型,
里面在__new__()的最后有一行“return super().__new__(cls, string)”,请问这一行是什么意思啊
案例中还继承了str类,我试了一下如果不继承类的话会报错,那这个__new__()是只有在继承了类的情况下才能使用吗

FishC 发表于 2024-7-20 09:49:30

小甲鱼的小伙伴,你的问题问得非常好!让我用鱼油喜欢的风格来解答你吧~

### 什么是 `__new__()`?

要理解 `__new__()`,我们得先知道 `__init__()`。`__init__()` 是用于初始化对象的,就像给新买的自行车装个铃铛、打个气那样。而 `__new__()` 则是负责创建这辆自行车的,它是比 `__init__()` 更早被调用的一个方法。

### `return super().__new__(cls, string)` 是啥意思?

先来看看这行代码:

return super().__new__(cls, string)

这行代码实际上是在调用父类(在这个例子中是 `str` 类)的 `__new__()` 方法,用来创建并返回一个新的实例。

- `super()` 函数会去调用当前类的父类(或者说基类),在这里就是 `str`。
- `super().__new__()` 意思就是调用 `str` 的 `__new__()` 方法。
- `cls` 是当前类(在继承链中的类)。
- `string` 是传递给这个方法的参数,通常是为了初始化你想要修改的内容。

搞笑一点解释就像是:你按了个神奇按钮(`super().__new__(cls, string)`),这个按钮告诉爸爸(`str` 类),“嘿,老爸,我需要一个新的字符串类型的物件,请给我搞一个吧!”

### 为什么要继承 `str` 类?

这是因为 `__new__()` 方法主要用在不可变类型(如 `str`、`int` 等)中,而这些类型的对象一旦创建就不能更改。所以,如果你不继承 `str` 类,你调用 `super().__new__()` 时,实际上找不到对应的 `__new__()` 方法,Python 就会报错。

举个例子:

class MyString(str):
    def __new__(cls, value):
      # 我们应该在这里创建一个新的字符串对象
      return super().__new__(cls, value)

# 创建一个自定义的字符串对象
my_str = MyString("Hello, FishC!")
print(my_str)# 输出: Hello, FishC!

如果你不继承 `str` 类,那就等于你想用鱼缸里的水来养鲸鱼,肯定不太合适啊!

### 总结

- `__new__()` 是用来创建对象的,比 `__init__()` 更早被调用。
- `return super().__new__(cls, string)` 是调用父类的 `__new__()` 方法来创建一个新的实例。
- 你需要继承一些不可变类型(如 `str`)才能合理使用 `__new__()` 方法。

希望这个解释能让你在学习Python的海洋里畅游无阻~ 有什么问题随时来问哦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

skyteam超级吕布 发表于 2024-7-20 10:05:07

FishC 发表于 2024-7-20 09:49
小甲鱼的小伙伴,你的问题问得非常好!让我用鱼油喜欢的风格来解答你吧~

### 什么是 `__new__()`?


那我不继承任何类的话,这个__new__()是不是就用不了了

FishC 发表于 2024-7-20 10:06:20

skyteam超级吕布 发表于 2024-07-20 10:05
那我不继承任何类的话,这个__new__()是不是就用不了 ...

其实不完全是那样的。`__new__()` 方法仍然是可以用的,即使你不继承任何类。

`__new__()` 方法是所有 Python 类都能用的,因为它是一个内置方法,也是 `object` 类的一部分。而所有类最终都继承自 `object`,所以理论上你总是可以重写 `__new__()` 方法。

不过,通常我们只在处理不可变类型(比如 `str`、`int` 和 `tuple`)时才会重写 `__new__()` 方法。如果你是处理可变类型(比如列表、字典),更常见的是在 `__init__()` 中进行初始化而不是重写 `__new__()`。

如果你不继承任何类,并且重写了 `__new__()`,你需要自己负责创建实例。举个例子:

class MyClass:
    def __new__(cls, *args, **kwargs):
      print("In __new__ method")
      instance = super().__new__(cls)# 调用object的__new__方法创建实例
      return instance

    def __init__(self, value):
      print("In __init__ method")
      self.value = value

# 创建一个MyClass的实例
my_instance = MyClass(10)
print(my_instance.value)# 输出: 10

这个代码里,我们没继承 `str` 或其他不可变类型,而是直接继承了 `object`。在 `__new__()` 方法,我们调用了 `super().__new__(cls)` 来实际创建一个实例,然后返回这个实例。

### 总结一下:

- 你可以在任何类中重写 `__new__()`,因为所有类最终都继承自 `object`。
- 通常只有在处理不可变类型时才需要重写 `__new__()`,对于可变类型更常见的是使用 `__init__()` 进行初始化。

希望这些解释让你更加清楚 `__new__()` 的用法啦!有什么其他问题随时来问哦,祝你在学习Python的道路上越走越远!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

skyteam超级吕布 发表于 2024-7-21 10:38:07

FishC 发表于 2024-7-20 10:06
其实不完全是那样的。`__new__()` 方法仍然是可以用的,即使你不继承任何类。

`__new__()` 方法是所 ...

在吗
页: [1]
查看完整版本: 类和对象__new__()