V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
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
mathzhaoliang
V2EX  ›  Python

Python 怎么初始化一个参数很多的类来着

  •  
  •   mathzhaoliang ·
    neozhaoliang · Feb 6, 2020 · 4974 views
    This topic created in 2274 days ago, the information mentioned may be changed or developed.

    假设有个类,其初始化函数如下

    class Foo:
        def __init__(self, name, age, gender, family, score, ...):
            self.name = name
            self.age = age
            self.gender = gender
            ...
    

    总之就是把参数列表里面所有的 args 和 kwargs 里的参数都变成类的属性变量。请问有什么简洁的办法吗?这样一个一个赋值太麻烦了。

    11 replies    2020-02-07 10:41:22 +08:00
    ericls
        1
    ericls  
       Feb 6, 2020 via iPhone
    **kwargs 或者直接传个 dict 或者别的什么 iterable
    watsy0007
        2
    watsy0007  
       Feb 6, 2020   ❤️ 2
    data_classes
    pengdirect
        3
    pengdirect  
       Feb 6, 2020 via iPhone
    *arg
    ipwx
        4
    ipwx  
       Feb 6, 2020 via Android
    优先选择 dataclass。不能用,就用 **kwargs, setattr
    imn1
        5
    imn1  
       Feb 6, 2020
    dataclass
    676529483
        6
    676529483  
       Feb 6, 2020
    虽然**kwargs 可以解决问题,但不觉得参数太多,应该抽象成单独的类传进去吗?
    ClericPy
        7
    ClericPy  
       Feb 6, 2020   ❤️ 7
    四种, https://paste.ubuntu.com/p/fMRyDqJPRY/

    ```python
    # 1. use dataclass at python3.7+, recommended
    from dataclasses import dataclass


    @dataclass
    class Data(object):
    a: int
    b: int
    c: int
    d: int


    data = Data(1, 2, 3, 4)
    print(data)
    # Data(a=1, b=2, c=3, d=4)
    print(data.a, data.b, data.c, data.d)
    # 1 2 3 4

    # 2. Use namedtuple

    from typing import NamedTuple


    class Data(NamedTuple):
    a: int
    b: int
    c: int
    d: int


    data = Data(1, 2, 3, 4)
    print(data)
    # Data(a=1, b=2, c=3, d=4)
    print(data.a, data.b, data.c, data.d)
    # 1 2 3 4

    # 3. Use __dict__ without __slots__


    class Data(object):

    def __init__(self, **kwargs):
    super().__init__()
    self.__dict__.update(kwargs)


    data = Data(a=1, b=2, c=3, d=4)
    print(data.a, data.b, data.c, data.d)
    # 1 2 3 4

    # 4. Use setattr with __slots__


    class Data(object):
    __slots__ = ('a', 'b', 'c', 'd')

    def __init__(self, **kwargs):
    super().__init__()
    for k, v in kwargs.items():
    setattr(self, k, v)


    data = Data(a=1, b=2, c=3, d=4)
    print(data.a, data.b, data.c, data.d)
    # 1 2 3 4

    ```

    作为一个程序员论坛, V 站貌似对代码支持的一塌糊涂
    PTLin
        8
    PTLin  
       Feb 6, 2020
    class Foo:
    def __init__(self, name, age):
    self.__dict__.update(locals())
    janxin
        9
    janxin  
       Feb 6, 2020
    dataclass for 3.7+
    attrs for 2.x/3.7-
    mathzhaoliang
        10
    mathzhaoliang  
    OP
       Feb 6, 2020
    我现在这个代码要兼容 python3.5 python3.6
    dataclass 看来用不了了
    watsy0007
        11
    watsy0007  
       Feb 7, 2020
    @mathzhaoliang 用不了用 NamedTuple
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1108 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 51ms · UTC 18:22 · PVG 02:22 · LAX 11:22 · JFK 14:22
    ♥ Do have faith in what you're doing.