代码之家  ›  专栏  ›  技术社区  ›  Simeon Leyzerzon mthmulders

functools在切换到python3时停止工作

  •  -1
  • Simeon Leyzerzon mthmulders  · 技术社区  · 6 年前

    map(functools.partial(self._assocUser, user=user), persistedGroupIds)
    

     for group_id in persistedGroupIds:
          self._assocUser(group_id, user)
    

        persistedGroupIds = map(functools.partial(self._persistGroup, grp_mappings=attrAll.entitlements), saml_authorization_attributes)  
    

    需要转到:

         persistedGroupIds = []
         for idp_group_name in saml_authorization_attributes:
             persistedGroupIds.append(self._persistGroup(idp_group_name, attrAll.entitlements))
    

    functools 好像不管用。

    下面是在Python2下运行良好的代码的完整列表:

        from django.contrib.auth.models import User
    from django.contrib.auth.models import Group
    import functools
    from mappings import SAMLAttributesConfig
    from django.conf import settings
    import logging
    
    log = logging.getLogger(__name__)
    
    class SAMLServiceProviderBackend(object):
    
        empty_entitlements_message="IdP supplied incorrect authorization entitlements.  Please contact their support."
    
        def _assocUser(self, group_id, user):
    
            group = Group.objects.get(id=group_id)
            group.user_set.add(user)
    
            return None
    
    
        def _persistGroup(self,idp_group_name, grp_mappings):
    
            group_name = grp_mappings[idp_group_name]
    
            try:
                group = Group.objects.get(name=group_name)
            except Group.DoesNotExist:
                group = Group(name=group_name)
                group.save()
    
            return group.id
    
        def _extract_grp_entitlements(self,saml_authentication_attributes,groups):
            result = []
            input_length = len(saml_authentication_attributes[groups])
            if input_length == 0:
                log.error(self.empty_entitlements_message)
                raise RuntimeError(self.empty_entitlements_message)
            if input_length == 1:
                result = [t.strip() for t in saml_authentication_attributes[groups][0].split(',')] 
            elif input_length:
                result = saml_authentication_attributes[groups]
            return result
    #         return [t.strip() for t in saml_authentication_attributes[groups][0].split(',')] \
    #             if len(saml_authentication_attributes[groups]) == 1\
    #             else saml_authentication_attributes[groups]
    
    
        def authenticate(self, saml_authentication=None):
            if not saml_authentication:  # Using another authentication method
                return None
    
            attrAll = SAMLAttributesConfig(mappings_file_name=settings.AUTH_MAPPINGS_FILE).get_config()
            groups = attrAll.entitlements.containerName
    
            if saml_authentication.is_authenticated():
    
                saml_authentication_attributes = saml_authentication.get_attributes()
                saml_authorization_attributes = self._extract_grp_entitlements(saml_authentication_attributes,groups)          
                persistedGroupIds = map(functools.partial(self._persistGroup, grp_mappings=attrAll.entitlements), saml_authorization_attributes)  
    
                try:
                    user = User.objects.get(username=saml_authentication.get_nameid())
                except User.DoesNotExist:
    
                    user = User(username=saml_authentication.get_nameid())
                    user.set_unusable_password()
                    try:
                        user.first_name = saml_authentication_attributes['samlNameId'][0]
                    except KeyError:
                        pass
                    try:
                        setattr(user, "first_name", saml_authentication_attributes[attrAll.subject.first_name][0])
    
                    except KeyError:
                        pass 
    
                    #user.last_name = attributes['Last name'][0]
                    user.save()
                    map(functools.partial(self._assocUser, user=user), persistedGroupIds)
                    user.save()
                return user
            return None
    
        def get_user(self, user_id):
            try:
                return User.objects.get(pk=user_id)
            except User.DoesNotExist:
                return None
    

    functools.partial() 用字母拼写的电话 for 回路:

    from django.contrib.auth.models import User
    from django.contrib.auth.models import Group
    import functools
    from .mappings import SAMLAttributesConfig
    from django.conf import settings
    import logging
    
    log = logging.getLogger(__name__)
    
    class SAMLServiceProviderBackend(object):
    
        empty_entitlements_message="IdP supplied incorrect authorization entitlements.  Please contact their support."
    
        def _assocUser(self, group_id, user):
    
            group = Group.objects.get(id=group_id)
            group.user_set.add(user)
    
            return None
    
    
        def _persistGroup(self,idp_group_name, grp_mappings):
    
            group_name = grp_mappings[idp_group_name]
    
            try:
                group = Group.objects.get(name=group_name)
            except Group.DoesNotExist:
                group = Group(name=group_name)
                group.save()
    
            return group.id
    
        def _extract_grp_entitlements(self,saml_authentication_attributes,groups):
            result = []
            input_length = len(saml_authentication_attributes[groups])
            if input_length == 0:
                log.error(self.empty_entitlements_message)
                raise RuntimeError(self.empty_entitlements_message)
            if input_length == 1:
                result = [t.strip() for t in saml_authentication_attributes[groups][0].split(',')] 
            elif input_length:
                result = saml_authentication_attributes[groups]
            return result
    #         return [t.strip() for t in saml_authentication_attributes[groups][0].split(',')] \
    #             if len(saml_authentication_attributes[groups]) == 1\
    #             else saml_authentication_attributes[groups]
    
    
        def authenticate(self, saml_authentication=None):
            if not saml_authentication:  # Using another authentication method
                return None
    
            attrAll = SAMLAttributesConfig(mappings_file_name=settings.AUTH_MAPPINGS_FILE).get_config()
            groups = attrAll.entitlements.containerName
    
            if saml_authentication.is_authenticated():
    
                saml_authentication_attributes = saml_authentication.get_attributes()
                saml_authorization_attributes = self._extract_grp_entitlements(saml_authentication_attributes,groups)          
                persistedGroupIds = map(functools.partial(self._persistGroup, grp_mappings=attrAll.entitlements), saml_authorization_attributes)  
    
                try:
                    user = User.objects.get(username=saml_authentication.get_nameid())
                except User.DoesNotExist:
    
                    user = User(username=saml_authentication.get_nameid())
                    user.set_unusable_password()
                    try:
                        user.first_name = saml_authentication_attributes['samlNameId'][0]
                    except KeyError:
                        pass
                    try:
                        setattr(user, "first_name", saml_authentication_attributes[attrAll.subject.first_name][0])
    
                    except KeyError:
                        pass 
    
                    #user.last_name = attributes['Last name'][0]
                    user.save()
                    for group_id in persistedGroupIds:
                        self._assocUser(user = user, group_id = group_id)
                    # map(functools.partial(self._assocUser, user=user), persistedGroupIds)
                    user.save()
                return user
            return None
    
        def get_user(self, user_id):
            try:
                return User.objects.get(pk=user_id)
            except User.DoesNotExist:
                return None
    

    有什么问题吗?

    我在Eclipse中使用PyDev插件。我的Python解释器是这样配置的:

    enter image description here


    enter image description here


    enter image description here

    以下是Eclipse的.pydevproject文件:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <?eclipse-pydev version="1.0"?><pydev_project>
    
    
    
        <pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">venv3.6</pydev_property>
    
    
    
        <pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python interpreter</pydev_property>
    
    
    
        <pydev_variables_property name="org.python.pydev.PROJECT_VARIABLE_SUBSTITUTION">
    
            <key>DJANGO_SETTINGS_MODULE</key>
    
            <value>reporting.settings</value>
    
            <key>DJANGO_MANAGE_LOCATION</key>
    
            <value>./manage.py</value>
    
            <key>SAML_PLUGIN</key>
    
            <value>/Users/sl/abc/venv3.6/lib/python3.6/site-packages/onelogin/saml2</value>
    
            <key>PY</key>
    
            <value>36</value>
    
        </pydev_variables_property>
    
    
    
        <pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
    
    
    
            <path>/${PROJECT_DIR_NAME}</path>
    
    
    
        </pydev_pathproperty>
    
    
    
        <pydev_pathproperty name="org.python.pydev.PROJECT_EXTERNAL_SOURCE_PATH">
    
            <path>${SAML_PLUGIN}</path>
    
        </pydev_pathproperty>
    
    
    </pydev_project>
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Simeon Leyzerzon mthmulders    6 年前

    在python3中,map函数 returns an iterator instead of a list

    这意味着如果你打电话 map 在一个集合上,调用的效果只有在您对结果迭代器进行迭代时才会具体化。

    考虑一下这个类:

    >>> class C:
    ...     def __init__(self, x):
    ...         self.x = x
    ...     def double(self):
    ...         self.x *= 2
    ...     def __repr__(self):                                                                                             
    ...         return '<C:{}>'.format(self.x)
    ... 
    

    让我们列一个实例列表:

    >>> cs = [C(x) for x in range(1, 4)]
    >>> cs
    [<C:1>, <C:2>, <C:3>]
    

    现在使用 地图 调用每个实例的 double 方法:

    >>> res = map(C.double, cs)
    

    >>> res
    <map object at 0x7ff276350470>
    

    实例没有改变:

    >>> cs
    [<C:1>, <C:2>, <C:3>]
    

    >>> next(res)
    >>> cs
    [<C:2>, <C:2>, <C:3>]
    >>> next(res)
    >>> cs
    [<C:2>, <C:4>, <C:3>]
    >>> next(res)
    >>> cs
    [<C:2>, <C:4>, <C:6>]
    

    在您提供的代码示例中,调用 地图 没有赋值给变量,所以 是用于它的副作用,而不是它的输出。在Python3中,正确的方法是循环iterable并调用每个元素上的函数:

    >>> for c in cs:
            c.double()
    

    正如链接文档所说:

    map() 调用函数的副作用;正确的转换是使用常规的for循环(因为创建一个列表只是浪费)。