<i id='xHP5G'><tr id='xHP5G'><dt id='xHP5G'><q id='xHP5G'><span id='xHP5G'><b id='xHP5G'><form id='xHP5G'><ins id='xHP5G'></ins><ul id='xHP5G'></ul><sub id='xHP5G'></sub></form><legend id='xHP5G'></legend><bdo id='xHP5G'><pre id='xHP5G'><center id='xHP5G'></center></pre></bdo></b><th id='xHP5G'></th></span></q></dt></tr></i><div id='xHP5G'><tfoot id='xHP5G'></tfoot><dl id='xHP5G'><fieldset id='xHP5G'></fieldset></dl></div>
  1. <tfoot id='xHP5G'></tfoot>
  2. <small id='xHP5G'></small><noframes id='xHP5G'>

    1. <legend id='xHP5G'><style id='xHP5G'><dir id='xHP5G'><q id='xHP5G'></q></dir></style></legend>

        <bdo id='xHP5G'></bdo><ul id='xHP5G'></ul>

      在 Python 中进行自动属性分配的最佳方法是什么,

      时间:2023-09-13
      <i id='IDoKg'><tr id='IDoKg'><dt id='IDoKg'><q id='IDoKg'><span id='IDoKg'><b id='IDoKg'><form id='IDoKg'><ins id='IDoKg'></ins><ul id='IDoKg'></ul><sub id='IDoKg'></sub></form><legend id='IDoKg'></legend><bdo id='IDoKg'><pre id='IDoKg'><center id='IDoKg'></center></pre></bdo></b><th id='IDoKg'></th></span></q></dt></tr></i><div id='IDoKg'><tfoot id='IDoKg'></tfoot><dl id='IDoKg'><fieldset id='IDoKg'></fieldset></dl></div>
        <tbody id='IDoKg'></tbody>
    2. <small id='IDoKg'></small><noframes id='IDoKg'>

        • <tfoot id='IDoKg'></tfoot>
            <bdo id='IDoKg'></bdo><ul id='IDoKg'></ul>
            1. <legend id='IDoKg'><style id='IDoKg'><dir id='IDoKg'><q id='IDoKg'></q></dir></style></legend>

                本文介绍了在 Python 中进行自动属性分配的最佳方法是什么,这是一个好主意吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                问题描述

                而不是每次定义类时都编写这样的代码:

                Instead of writing code like this every time I define a class:

                class Foo(object): 
                     def __init__(self, a, b, c, d, e, f, g):
                        self.a = a
                        self.b = b
                        self.c = c
                        self.d = d
                        self.e = e
                        self.f = f
                        self.g = g
                

                我可以使用这个自动属性分配方法.

                class Foo(object):
                     @autoassign
                     def __init__(self, a, b, c, d, e, f, g):
                        pass
                

                两个问题:

                1. 是否存在与此快捷方式相关的缺点或陷阱?
                2. 有没有更好的方法来实现类似的便利?

                推荐答案

                关于自动分配代码的一些问题让我感到困惑(主要是风格,但还有一个更严重的问题):

                There are some things about the autoassign code that bug me (mostly stylistic, but one more serious problem):

                1. autoassign 不分配'args' 属性:

                1. autoassign does not assign an 'args' attribute:

                class Foo(object):
                    @autoassign
                    def __init__(self,a,b,c=False,*args):
                        pass
                a=Foo('IBM','/tmp',True, 100, 101)
                print(a.args)
                # AttributeError: 'Foo' object has no attribute 'args'
                

              • autoassign 就像一个装饰器.但是 autoassign(*argnames) 调用返回装饰器的函数.为了实现这个魔力,autoassign需要先测试它的类型争论.如果可以选择,我喜欢功能而不是测试其参数的类型.

              • autoassign acts like a decorator. But autoassign(*argnames) calls a function which returns a decorator. To achieve this magic, autoassign needs to test the type of its first argument. If given a choice, I prefer functions not test the type of its arguments.

                好像有很多用于设置的代码量筛子,lambdas中的lambdas,ifilters,还有很多条件.

                There seems to be a considerable amount of code devoted to setting up sieve, lambdas within lambdas, ifilters, and lots of conditions.

                if kwargs:
                    exclude, f = set(kwargs['exclude']), None
                    sieve = lambda l:itertools.ifilter(lambda nv: nv[0] not in exclude, l)
                elif len(names) == 1 and inspect.isfunction(names[0]):
                    f = names[0]
                    sieve = lambda l:l
                else:
                    names, f = set(names), None
                    sieve = lambda l: itertools.ifilter(lambda nv: nv[0] in names, l)
                

                我认为可能有更简单的方法.(看下面).

                I think there might be a simpler way. (See below).

                for _ initertools.starmap(assigned.setdefault,默认值):通过.我不认为mapstarmap 旨在调用函数,其唯一目的是它们的副作用.本来可以用平凡写得更清楚:

                for _ in itertools.starmap(assigned.setdefault, defaults): pass. I don't think map or starmap was meant to call functions, whose only purpose is their side effects. It could have been written more clearly with the mundane:

                for key,value in defaults.iteritems():
                    assigned.setdefault(key,value)
                

              • 这是一个替代的更简单的实现,它具有与自动分配相同的功能(例如,可以包含和排除),并且解决了上述问题:

                Here is an alternative simpler implementation which has the same functionality as autoassign (e.g. can do includes and excludes), and which addresses the above points:

                import inspect
                import functools
                
                def autoargs(*include, **kwargs):
                    def _autoargs(func):
                        attrs, varargs, varkw, defaults = inspect.getargspec(func)
                
                        def sieve(attr):
                            if kwargs and attr in kwargs['exclude']:
                                return False
                            if not include or attr in include:
                                return True
                            else:
                                return False
                
                        @functools.wraps(func)
                        def wrapper(self, *args, **kwargs):
                            # handle default values
                            if defaults:
                                for attr, val in zip(reversed(attrs), reversed(defaults)):
                                    if sieve(attr):
                                        setattr(self, attr, val)
                            # handle positional arguments
                            positional_attrs = attrs[1:]
                            for attr, val in zip(positional_attrs, args):
                                if sieve(attr):
                                    setattr(self, attr, val)
                            # handle varargs
                            if varargs:
                                remaining_args = args[len(positional_attrs):]
                                if sieve(varargs):
                                    setattr(self, varargs, remaining_args)
                            # handle varkw
                            if kwargs:
                                for attr, val in kwargs.items():
                                    if sieve(attr):
                                        setattr(self, attr, val)
                            return func(self, *args, **kwargs)
                        return wrapper
                    return _autoargs
                

                这是我用来检查其行为的单元测试:

                And here is the unit test I used to check its behavior:

                import sys
                import unittest
                import utils_method as um
                
                class Test(unittest.TestCase):
                    def test_autoargs(self):
                        class A(object):
                            @um.autoargs()
                            def __init__(self,foo,path,debug=False):
                                pass
                        a=A('rhubarb','pie',debug=True)
                        self.assertTrue(a.foo=='rhubarb')
                        self.assertTrue(a.path=='pie')
                        self.assertTrue(a.debug==True)
                
                        class B(object):
                            @um.autoargs()
                            def __init__(self,foo,path,debug=False,*args):
                                pass
                        a=B('rhubarb','pie',True, 100, 101)
                        self.assertTrue(a.foo=='rhubarb')
                        self.assertTrue(a.path=='pie')
                        self.assertTrue(a.debug==True)
                        self.assertTrue(a.args==(100,101))        
                
                        class C(object):
                            @um.autoargs()
                            def __init__(self,foo,path,debug=False,*args,**kw):
                                pass
                        a=C('rhubarb','pie',True, 100, 101,verbose=True)
                        self.assertTrue(a.foo=='rhubarb')
                        self.assertTrue(a.path=='pie')
                        self.assertTrue(a.debug==True)
                        self.assertTrue(a.verbose==True)        
                        self.assertTrue(a.args==(100,101))        
                
                    def test_autoargs_names(self):
                        class C(object):
                            @um.autoargs('bar','baz','verbose')
                            def __init__(self,foo,bar,baz,verbose=False):
                                pass
                        a=C('rhubarb','pie',1)
                        self.assertTrue(a.bar=='pie')
                        self.assertTrue(a.baz==1)
                        self.assertTrue(a.verbose==False)
                        self.assertRaises(AttributeError,getattr,a,'foo')
                
                    def test_autoargs_exclude(self):
                        class C(object):
                            @um.autoargs(exclude=('bar','baz','verbose'))
                            def __init__(self,foo,bar,baz,verbose=False):
                                pass
                        a=C('rhubarb','pie',1)
                        self.assertTrue(a.foo=='rhubarb')
                        self.assertRaises(AttributeError,getattr,a,'bar')
                
                    def test_defaults_none(self):
                        class A(object):
                            @um.autoargs()
                            def __init__(self,foo,path,debug):
                                pass
                        a=A('rhubarb','pie',debug=True)
                        self.assertTrue(a.foo=='rhubarb')
                        self.assertTrue(a.path=='pie')
                        self.assertTrue(a.debug==True)
                
                
                if __name__ == '__main__':
                    unittest.main(argv = sys.argv + ['--verbose'])
                

                PS.使用 autoassignautoargs 与 IPython 代码完成兼容.

                PS. Using autoassign or autoargs is compatible with IPython code completion.

                这篇关于在 Python 中进行自动属性分配的最佳方法是什么,这是一个好主意吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                上一篇:如何在 Windows 中使用 Python 删除只读属性目录? 下一篇:如何使用 Python 的 zipfile 模块对 ZIP 文件中的文件

                相关文章

                最新文章

                1. <legend id='6wxnJ'><style id='6wxnJ'><dir id='6wxnJ'><q id='6wxnJ'></q></dir></style></legend>
                  1. <tfoot id='6wxnJ'></tfoot>

                    <i id='6wxnJ'><tr id='6wxnJ'><dt id='6wxnJ'><q id='6wxnJ'><span id='6wxnJ'><b id='6wxnJ'><form id='6wxnJ'><ins id='6wxnJ'></ins><ul id='6wxnJ'></ul><sub id='6wxnJ'></sub></form><legend id='6wxnJ'></legend><bdo id='6wxnJ'><pre id='6wxnJ'><center id='6wxnJ'></center></pre></bdo></b><th id='6wxnJ'></th></span></q></dt></tr></i><div id='6wxnJ'><tfoot id='6wxnJ'></tfoot><dl id='6wxnJ'><fieldset id='6wxnJ'></fieldset></dl></div>
                    • <bdo id='6wxnJ'></bdo><ul id='6wxnJ'></ul>

                    <small id='6wxnJ'></small><noframes id='6wxnJ'>