V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Richard14
V2EX  ›  Python

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

  •  
  •   Richard14 · 2022-12-17 23:49:19 +08:00 · 2742 次点击
    这是一个创建于 725 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    # 也就是把常见的
    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 读取

    9 条回复    2022-12-19 10:59:52 +08:00
    Yourshell
        1
    Yourshell  
       2022-12-17 23:52:39 +08:00 via Android   ❤️ 1
    UserString
    milkpuff
        2
    milkpuff  
       2022-12-18 01:39:20 +08:00
    https://www.v2ex.com/t/743574
    之前看过一篇实现了这个竖杠。
    inframe
        3
    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
        4
    NoAnyLove  
       2022-12-18 02:13:09 +08:00
    没看懂,为啥不用 json.load?
    Richard14
        5
    Richard14  
    OP
       2022-12-18 02:53:21 +08:00
    @NoAnyLove 希望能同时支持 json.loads.read()和 read().json.loads 的写法,两者写码时逻辑顺序不同。
    zhengjian
        6
    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
        7
    zhengjian  
       2022-12-18 03:22:43 +08:00
    krixaar
        8
    krixaar  
       2022-12-19 10:42:17 +08:00
    像 requests 那样 r.text r.json()不就挺好的么?
    julyclyde
        9
    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())
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2667 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 71ms · UTC 14:39 · PVG 22:39 · LAX 06:39 · JFK 09:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.