首页 > 解决方案 > 方法参数改变结果。如何?

问题描述

我正在开发一个可以输出 HTML 代码的 Python 模块。当我尝试创建子元素并尝试添加属性(例如 id 或样式)时,它会将属性添加到父元素和所有其他子元素;但是我在课堂上改变了一些东西并修复了它,这让我对它的工作原理感到困惑。原始类 __init__ 如下所示:

ezhtml.py(类元素)

    def __init__(self, tag_: str, attr=dict(), text=str()):
        '''
            tag_ : the HTML tag for the element
            attr : a dictionary containing any attributes required for the element (can be added later)
            text : the innerText for the HTML element
        '''
        self.__tag = tag_
        self.__Attributes = attr
        self.__children = {}
        self.__text_order = True
        self.__text = text

        for key in self.__Attributes.keys():
            setattr(self, key, self.__Attributes[key])

制作一个简单网站的代码如下所示:

示例.py

from ezhtml import *

html = Element("html")

head = Element('head')
html.appendChild(head)
html.head.appendChild(Element('title', text='Title To My Webpage'))

html.appendChild(Element('body'))

html.body.appendChild(Element('h1'))
html.body.h1.add_attr('style', 'background-color: black; color: white; text-align: center;')
html.body.h1.text = "Hello world"
print(html)

所需的输出如下:

<html>
        <head>
                <title>Title To My Webpage</title>
        </head>
        <body>
                <h1 style="background-color: black; color: white; text-align: center;">Hello world</h1>
        </body>
</html>

然而我得到的输出是这样的:

<html style="background-color: black; color: white; text-align: center;">
        <head style="background-color: black; color: white; text-align: center;">
                <title style="background-color: black; color: white; text-align: center;">Title To My Webpage</title>
        </head>
        <body style="background-color: black; color: white; text-align: center;">
                <h1 style="background-color: black; color: white; text-align: center;">Hello world</h1>
        </body>
</html>

然后我搞砸了并将__init__方法更改为以下内容:

def __init__(self, tag_: str, attr=None, text=str()):
        '''
            tag_ : the HTML tag for the element
            attr : a dictionary containing any attributes required for the element (can be added later)
            text : the innerText for the HTML element
        '''
        self.__tag = tag_
        if attr is None:
            self.__Attributes = dict()
        else:
            self.__Attributes = attr
        self.__children = {}
        self.__text_order = True
        self.__text = text

        for key in self.__Attributes.keys():
            setattr(self, key, self.__Attributes[key])

这给了我想要的输出。我看不出这应该如何改变任何事情,但它奏效了,给了我想要的结果。我只是好奇这是如何或为什么起作用的。

标签: pythonpython-3.xmethods

解决方案


出现这种行为是因为您的 Elements 类的定义中有“attr=dict()”。这意味着在定义 Elements 时会创建一个字典对象(不是每次创建新的 Elements 对象时都创建一个新的字典对象)。因此,每个新的 Elements 对象都使用同一个字典对象。“add_attr”方法可能会更新“attr”字典 - 但它会为所有 Elements 类成员这样做。您对 Elements 的第二个定义正是如何避免这个问题的方法。

另请参阅: https ://docs.python-guide.org/writing/gotchas/


推荐阅读