Python 的自定义类继承自 str 类的方式?

2022-12-17 23:49:19 +08:00
 Richard14

想要自己写一个类,简化一下平时常用的读取文件的过程,

# 也就是把常见的
with open('file.txt', 'r', encoding='utf-8') as f:
    text = f.read()
# 简化成
text = Read('file.txt')

但是最近发现涉及到解码的话还是有些不爽,比如 json 读取

# 目前的写法
dict_ = json.loads(Read('my_dict.json'))
# 理想中的写法,除上文调用方式外还应支持类似链式调用的方式
dict_ = Read('my_dict.json') | json.loads

感觉实现起来比较困难,如何让一个类普通时候能当做 str 使用,还能覆盖它的魔术方法,使其支持链式调用呢?我试了试 class Read(str)这种定义方式,结果类无法被 json.loads 读取

2577 次点击
所在节点    Python
9 条回复
Yourshell
2022-12-17 23:52:39 +08:00
UserString
milkpuff
2022-12-18 01:39:20 +08:00
https://www.v2ex.com/t/743574
之前看过一篇实现了这个竖杠。
inframe
2022-12-18 02:04:01 +08:00
https://docs.python.org/3/library/pathlib.html#pathlib.Path.read_text

p = Path('my_text_file')
p.write_text('Text file contents')
p.read_text()
'Text file contents'

单纯文件操作 Pathlib 内置库就够用
NoAnyLove
2022-12-18 02:13:09 +08:00
没看懂,为啥不用 json.load?
Richard14
2022-12-18 02:53:21 +08:00
@NoAnyLove 希望能同时支持 json.loads.read()和 read().json.loads 的写法,两者写码时逻辑顺序不同。
zhengjian
2022-12-18 03:18:19 +08:00
感觉可以,但没必要

```python
import json


class Read(str):
def __new__(cls, filepath):
with open(filepath, 'r', encoding='utf-8') as f:
# return super(Read, cls).__new__(cls, f.read())
return Read.__make_str(f.read())

@classmethod
def __make_str(cls, value):
return super(Read, cls).__new__(cls, value)

def loads_to_json(self):
return json.loads(self)

def strip(self, char = " "):
return Read.__make_str(super().strip(char))

def replace(self, *args):
return Read.__make_str(super().replace(*args))


# use as str
file_content = Read("file.txt")

print("file_content: " + file_content.strip())

print(json.loads(file_content))

# chaining
jsonContent = Read("file.txt").replace("hell0", "hello").loads_to_json()

print(jsonContent.get("message"))
```

output:

```shell

➜ Downloads python3 v2ex.py
file_content: {"message" : "hell0, world!"}

{'message': 'hell0, world!'}
hello, world!
```
zhengjian
2022-12-18 03:22:43 +08:00
krixaar
2022-12-19 10:42:17 +08:00
像 requests 那样 r.text r.json()不就挺好的么?
julyclyde
2022-12-19 10:59:52 +08:00
```
import json

class Read():
def __init__(self, filename):
super(Read, self).__init__()
self.filename = filename

def __str__(self):
return open(self.filename, "r").read()

def loads(self):
return json.loads(self.__str__())

i = Read("2.json")
print(type(i))
print(i)
print(i.loads())
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/903214

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX