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
pebble329
V2EX  ›  Python

Python 函数如果不在类中是否可以实现链式操作?

  •  
  •   pebble329 · 2020-03-27 15:21:38 +08:00 · 2120 次点击
    这是一个创建于 1488 天前的主题,其中的信息可能已经有所发展或是发生改变。
    建立文件 np_cn.py 如下

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    import numpy
    def 变换形状(序列, 新形状, 顺序='C'):
    return numpy.reshape(a = 序列, newshape = 新形状, order = 顺序)
    def 有序序列(*args, **kwargs):
    return numpy.arange(*args, **kwargs)

    然后导入改文件,运行两个函数都没有问题,

    from np1 import np_cn_9 as nmp
    nmp.变换形状( nmp.有序序列(9),(3,3))

    结果是:
    array([[0, 1, 2],
    [3, 4, 5],
    [6, 7, 8]])

    运行 nmp.有序序列(9).变换形状( (3,3))

    结果为
    ---------------------------------------------------------------------------
    AttributeError Traceback (most recent call last)
    <ipython-input-7-ce82a699b849> in <module>()
    ----> 1 nmp.有序序列(9).变换形状( (3,3))

    AttributeError: 'numpy.ndarray' object has no attribute '变换形状'

    如果不想把这些函数都放到一个类中,应该如何写代码才能实现链式操作,目前个人想法是用装饰器,还没想好怎么用。谢谢!
    6 条回复    2020-03-29 13:16:24 +08:00
    xpresslink
        1
    xpresslink  
       2020-03-27 17:17:07 +08:00
    如果要实现 XX.m1().m2().m3()这种链式调用模式。
    那么
    XX.m1()的返回结果必然要是一个包含 m2 方法(属性)的类,
    同理 m2()的返回结果必然要是一个包含 m3 方法(属性)的类
    这些都是绕不过去的,是不是把 m1~3 都写在一个类里面不绝对。
    可是为了方便传递数据,用一个类可能方便一点,例如给类加一个_data = {}/[] 属性存储数据结果。
    xpresslink
        2
    xpresslink  
       2020-03-27 17:18:01 +08:00
    上面的类的说得不准确,应该是对象。
    xpresslink
        3
    xpresslink  
       2020-03-27 17:23:49 +08:00
    >>> ['abc'].pop().find('b').__bool__()
    True
    fzhyzamt
        4
    fzhyzamt  
       2020-03-27 18:17:42 +08:00
    大概这样?
    ```python
    #!/usr/bin/python
    # -*- coding: UTF-8 -*-

    import sys

    current_module = sys.modules[__name__]


    class Chain:
    def __init__(self, *args):
    self.args = args

    def __getattr__(self, item):
    raw_func = getattr(current_module, item)

    def _inner(*args):
    chain = raw_func(*self.args, *args)
    self.args = chain.args
    return chain

    return _inner


    def a(*args):
    print('func[a]', *args)
    return Chain(f'Result:a{str(args)}')


    def b(*args):
    print('func[b]', *args)
    return Chain(f'Result:b{str(args)}')


    a(1, 2, 3).b(4, 5).a(7, 7, 7).a(6, 6)
    ```
    输出:
    ```
    func[a] 1 2 3
    func[b] Result:a(1, 2, 3) 4 5
    func[a] Result:b('Result:a(1, 2, 3)', 4, 5) 7 7 7
    func[a] Result:a("Result:b('Result:a(1, 2, 3)', 4, 5)", 7, 7, 7) 6 6
    ```
    alxia
        5
    alxia  
       2020-03-28 10:23:28 +08:00
    试了一下 np.array 禁止动态绑定属性,所以你想要的效果是无法实现的,只能自己写类
    pebble329
        6
    pebble329  
    OP
       2020-03-29 13:16:24 +08:00
    第一次提问,谢谢大家的答复。

    暂时还是继承了一个对象


    import numpy
    class cn_array(np.ndarray):
    def __new__(cls, input_array, info=None):
    obj = np.asarray(input_array).view(cls)
    return obj
    def __array_finalize__(self, obj):
    if obj is None: return


    def 一序列(形状, 数据类型=None, 顺序='C'):
    return cn_array(numpy.ones(shape = 形状, dtype = 数据类型, order = 顺序))

    def 变换形状(序列, 新形状, 顺序='C'):
    return cn_array(numpy.reshape(a = 序列, newshape = 新形状, order = 顺序))

    序列 1 = cn_array
    序列 1.一序列(9).变换形状((3,3))

    运行结果是

    cn_array([[1., 1., 1.],
    [1., 1., 1.],
    [1., 1., 1.]])

    结果还可以接受,就是不能使用类似 'inport numpy as np' 这样的句子了!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3284 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 13:57 · PVG 21:57 · LAX 06:57 · JFK 09:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.