如何使Python子类控制存储在不可变实例中的数据?

如何使Python子类控制存储在不可变实例中的数据?

首先,理解Python中的new()方法。当子类化不可变类型时,重写new()方法,而不是init()方法。

new方法在创建对象时被调用,而init方法将被调用来初始化该对象。这些是魔术方法。

魔术方法允许我们在面向对象编程中做一些非常酷的技巧。它们也被称为Dunder方法。这些方法由两个下划线(__)作为前缀和后缀来标识。

显示从int类继承的魔术方法

例子

使用fir()可以打印魔术方法 –

print(dir(int))

输出

['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__',
 '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', 
'__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__'
, '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__',
 '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', 
'__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', 
'__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', 
'__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'bit_length', 'conjugate',
 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

init()

例子

让我们看一个使用init()魔术方法实例化对象的例子 –

class String:
   # 初始化对象的魔术方法
   def __init__(self, string):
      self.string = string

# 驱动代码
if __name__ == '__main__':
   # 创建对象
   myStr = String('Demo')
   # 打印对象位置
   print(myStr)

输出

<__main__.String object at 0x7f34c97799d0>

子类化不可变类型

例子

现在,让我们看一下如何使Python子类控制存储在不可变实例中的数据。

from datetime import date

class FirstOfMonthDate(date):
   "选择每月的第一天"
   def __new__(cls, year, month, day):
      return super().__new__(cls, year, month, 1)

class NamedInt(int):
   "使用一些数字的文本名称"
   xlat = {'zero': 0, 'one': 1, 'ten': 10, 'fifteen': 15}
   def __new__(cls, value):
      value = cls.xlat.get(value, value)
      return super().__new__(cls, value)

class TitleStr(str):
   "将字符串转换为适用于URL路径的名称"
   def __new__(cls, s):
      s = s.lower().replace(' ', '-')
      s = ''.join([c for c in s if c.isalnum() or c == '-'])
      return super().__new__(cls, s)

# 调用
print(FirstOfMonthDate(2022, 9, 8))
print(NamedInt('fifteen'))
print(NamedInt(18))

# 创建URL路径
print(TitleStr('course for beginners'))

输出

2022-09-01
15
18
course-for-beginners

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程