【问题标题】:Convert Variable Name to String?将变量名转换为字符串?
【发布时间】:2010-12-04 19:19:38
【问题描述】:

我想将 python 变量名称转换为等效的字符串,如图所示。有什么想法吗?

var = {}
print ???  # Would like to see 'var'
something_else = 3
print ???  # Would print 'something_else'

【问题讨论】:

  • 您能否详细说明您想要实现的目标?似乎您在问如何以错误的方式解决问题。此外,还有一个类似的问题,但关于 Ruby stackoverflow.com/questions/58482/ruby-get-a-variables-name
  • 我检查了这个问题,因为使用 RPy2,我想传递一个带有同名 R 名称的 Python 变量。一个无用的(但接近我的应用程序)示例:def to_R( py_var ): r.assign( 'py_var', py_var ) 将 (Py) py_var 中的数据分配给 R 环境并具有相同的名称。这样做对我很有用,r.assign( py_var.stringof, py_var ) a la D 因为传递给我的 fn to_r 的变量名不一定是 py_var
  • 使用它的一种方法是当 Assert 语句失败时。您可以为用户提供有问题的确切变量名称,同时保持代码通用,例如AssertionError: 'something_else' 必须是大于 5 的数字。然后您可以测试每个需要大于 5 的变量,并在 AssertionError 消息中获取变量名称。

标签: python string variables


【解决方案1】:
print "var"
print "something_else"

或者你的意思是什么_else?

【讨论】:

    【解决方案2】:

    您必须以某种方式引用要打印其名称的变量。所以它看起来像:

    print varname(something_else)
    

    没有这样的功能,但如果有,那将毫无意义。您必须输入something_else,因此您也可以在其左右输入引号以将名称打印为字符串:

    print "something_else"
    

    【讨论】:

    • 这应该是评论,而不是答案。
    • 我在下面创建了一个varname 函数。也适用于方法。
    • 这是错误的。我想在循环中检查变量的名称!所以,我不能打字,也不是没有意义!
    【解决方案3】:

    这是不可能的。

    在 Python 中,实际上没有“变量”之类的东西。 Python 真正拥有的是可以绑定对象的“名称”。对象可能绑定的名称(如果有的话)对对象没有任何影响。它可能绑定了几十个不同的名称,或者没有。

    考虑这个例子:

    foo = 1
    bar = 1
    baz = 1
    

    现在,假设您有一个值为 1 的整数对象,并且您想要向后工作并找到它的名称。你会打印什么?三个不同的名称都绑定了该对象,并且都同样有效。

    在 Python 中,名称是访问对象的一种方式,因此无法直接使用名称。可能有一些聪明的方法可以破解 Python 字节码或获取名称的值,但这充其量只是一个小把戏。

    如果你知道你想让print foo 打印"foo",你不妨一开始就执行print "foo"

    编辑:我稍微改变了措辞以使这一点更清楚。另外,这里有一个更好的例子:

    foo = 1
    bar = foo
    baz = foo
    

    实际上,Python 对具有常见值(例如 0 或 1)的整数重用相同的对象,因此第一个示例应该将相同的对象绑定到所有三个名称。但是这个例子非常清楚:同一个对象绑定到 foo、bar 和 baz。

    【讨论】:

    • 对象没有名字,名字有对象
    • 有一种方法可以使用这些名称,即 globals() 字典,但尚不清楚如何使用它来完成 OP 要求的操作。
    • 当然,有可能。并且非常微不足道(无论如何它解决了OP的问题)。这只是没有人应该想做的事情。
    • 你说不可能。还是有可能的。查看其他答案。 @SilentGhost:您能否澄清一下为什么“没有人应该这样做”?我想这取决于应用程序。你的论点是什么?
    • @Robyc 你说“还有可能”。好的。我给出了将foo barbaz 全部绑定到1 的示例。那么1 的“名字”是什么?如果您查看所有全局变量,您可以返回变量名称列表:['foo', 'bar', 'baz'](以某种随机顺序)。好的。这个清单有什么用?其中一个名称是1 的“真实”名称吗? (不。)我们这些说“它”的人不可能都同意您可以查看全局变量并找到所有名称;我们只是不认为这是一件有用的事情。正如我所说:一个对象“可能绑定到几十个不同的名称,或者没有。”
    【解决方案4】:

    从技术上讲,您可以使用这些信息,但正如其他人所问的,您将如何以合理的方式使用它?

    >>> x = 52
    >>> globals()
    {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 
    'x': 52, '__doc__': None, '__package__': None}
    

    这表明变量名在 globals() 字典中以字符串的形式存在。

    >>> globals().keys()[2]
    'x'
    

    在这种情况下,它恰好是第三个键,但没有可靠的方法可以知道给定变量名称的结束位置

    >>> for k in globals().keys():
    ...   if not k.startswith("_"):
    ...     print k
    ...
    x
    >>>
    

    你可以像这样过滤掉系统变量,但你仍然会得到你自己的所有项目。刚刚运行上面的代码创建了另一个变量“k”,它改变了“x”在字典中的位置。

    但也许这对你来说是一个有用的开始。如果您告诉我们您想要此功能的用途,可能会提供更多有用的信息。

    【讨论】:

    • 克里斯,您的评论似乎与我的回答或原始问题无关。你在骂谁,为什么?你不知道他是在编写生产代码还是只是为了自己的教育而尝试语言功能。
    【解决方案5】:

    你想达到什么目的?绝对没有理由去做你所描述的事情,并且对于你试图解决的问题可能有更好的解决方案..

    您要求的最明显的替代方法是字典。例如:

    >>> my_data = {'var': 'something'}
    >>> my_data['something_else'] = 'something'
    >>> print my_data.keys()
    ['var', 'something_else']
    >>> print my_data['var']
    something
    

    主要是作为一个.. 挑战,我实现了您想要的输出。请不要使用此代码!

    #!/usr/bin/env python2.6
    class NewLocals:
        """Please don't ever use this code.."""
        def __init__(self, initial_locals):
            self.prev_locals = list(initial_locals.keys())
    
        def show_new(self, new_locals):
            output = ", ".join(list(set(new_locals) - set(self.prev_locals)))
            self.prev_locals = list(new_locals.keys())
            return output
    # Set up
    eww = None
    eww = NewLocals(locals())
    
    # "Working" requested code
    
    var = {}
    
    print eww.show_new(locals())  # Outputs: var
    
    something_else = 3
    print eww.show_new(locals()) # Outputs: something_else
    
    # Further testing
    
    another_variable = 4
    and_a_final_one = 5
    
    print eww.show_new(locals()) # Outputs: another_variable, and_a_final_one
    

    【讨论】:

    • 这很酷,但就像我想要的那样自动。感谢您的提示 =]
    • “绝对没有理由做你所描述的事情” - 我们在这里有一个本地无所不知的实体。实际上有一些很好的用例。
    【解决方案6】:

    TL;DR:不可能。见最后的“结论”。


    有一个使用场景,您可能需要它。我并不是暗示没有更好的方法或实现相同的功能。

    这对于在出错、调试模式和其他类似情况下“转储”任意字典列表很有用。

    需要的是 eval() 函数的反函数:

    get_indentifier_name_missing_function()
    

    将标识符名称('变量','字典'等)作为参数,并返回一个 包含标识符名称的字符串。


    考虑以下现状:

    random_function(argument_data)
    

    如果将标识符名称('function'、'variable'、'dictionary'等)argument_data 传递给random_function()(另一个标识符名称),则实际上传递一个标识符(例如:&lt;argument_data object at 0xb1ce10&gt; ) 到另一个标识符(例如:&lt;function random_function at 0xafff78&gt;):

    <function random_function at 0xafff78>(<argument_data object at 0xb1ce10>)
    

    据我了解,只有内存地址被传递给函数:

    <function at 0xafff78>(<object at 0xb1ce10>)
    

    因此,需要将字符串作为参数传递给random_function(),以便该函数具有参数的标识符名称:

    random_function('argument_data')
    

    random_function()内部

    def random_function(first_argument):
    

    ,可以使用已经提供的字符串'argument_data' 来:

    1. 用作“标识符名称”(用于显示、记录、字符串拆分/合并等)

    2. 输入eval() 函数以获得对实际标识符的引用,从而获得对真实数据的引用:

      print("Currently working on", first_argument)
      some_internal_var = eval(first_argument)
      print("here comes the data: " + str(some_internal_var))
      

    不幸的是,这并不适用于所有情况。它仅在random_function() 可以将'argument_data' 字符串解析为实际标识符时才有效。 IE。如果argument_data 标识符名称在random_function() 的命名空间中可用。

    情况并非总是如此:

    # main1.py
    import some_module1
    
    argument_data = 'my data'
    
    some_module1.random_function('argument_data')
    
    
    # some_module1.py
    def random_function(first_argument):
        print("Currently working on", first_argument)
        some_internal_var = eval(first_argument)
        print("here comes the data: " + str(some_internal_var))
    ######
    

    预期结果是:

    Currently working on: argument_data
    here comes the data: my data
    

    因为argument_data 标识符名称在random_function() 的命名空间中不可用,这将改为:

    Currently working on argument_data
    Traceback (most recent call last):
      File "~/main1.py", line 6, in <module>
        some_module1.random_function('argument_data')
      File "~/some_module1.py", line 4, in random_function
        some_internal_var = eval(first_argument)
      File "<string>", line 1, in <module>
    NameError: name 'argument_data' is not defined
    

    现在,考虑 get_indentifier_name_missing_function() 的假设用法,其行为如上所述。

    这是一个虚拟的 Python 3.0 代码:.

    # main2.py
    import some_module2
    some_dictionary_1       = { 'definition_1':'text_1',
                                'definition_2':'text_2',
                                'etc':'etc.' }
    some_other_dictionary_2 = { 'key_3':'value_3',
                                'key_4':'value_4', 
                                'etc':'etc.' }
    #
    # more such stuff
    #
    some_other_dictionary_n = { 'random_n':'random_n',
                                'etc':'etc.' }
    
    for each_one_of_my_dictionaries in ( some_dictionary_1,
                                         some_other_dictionary_2,
                                         ...,
                                         some_other_dictionary_n ):
        some_module2.some_function(each_one_of_my_dictionaries)
    
    
    # some_module2.py
    def some_function(a_dictionary_object):
        for _key, _value in a_dictionary_object.items():
            print( get_indentifier_name_missing_function(a_dictionary_object)    +
                   "    " +
                   str(_key) +
                   "  =  " +
                   str(_value) )
    ######
    

    预期结果是:

    some_dictionary_1    definition_1  =  text_1
    some_dictionary_1    definition_2  =  text_2
    some_dictionary_1    etc  =  etc.
    some_other_dictionary_2    key_3  =  value_3
    some_other_dictionary_2    key_4  =  value_4
    some_other_dictionary_2    etc  =  etc.
    ......
    ......
    ......
    some_other_dictionary_n    random_n  =  random_n
    some_other_dictionary_n    etc  =  etc.
    

    很遗憾,get_indentifier_name_missing_function() 不会看到“原始”标识符名称(some_dictionary_some_other_dictionary_2some_other_dictionary_n)。它只会看到 a_dictionary_object 标识符名称。

    因此,真正的结果宁愿是:

    a_dictionary_object    definition_1  =  text_1
    a_dictionary_object    definition_2  =  text_2
    a_dictionary_object    etc  =  etc.
    a_dictionary_object    key_3  =  value_3
    a_dictionary_object    key_4  =  value_4
    a_dictionary_object    etc  =  etc.
    ......
    ......
    ......
    a_dictionary_object    random_n  =  random_n
    a_dictionary_object    etc  =  etc.
    

    因此,在这种情况下,eval() 函数的反函数将没有那么有用。


    目前,需要这样做:

    # main2.py same as above, except:
    
        for each_one_of_my_dictionaries_names in ( 'some_dictionary_1',
                                                   'some_other_dictionary_2',
                                                   '...',
                                                   'some_other_dictionary_n' ):
            some_module2.some_function( { each_one_of_my_dictionaries_names :
                                         eval(each_one_of_my_dictionaries_names) } )
        
        
        # some_module2.py
        def some_function(a_dictionary_name_object_container):
            for _dictionary_name, _dictionary_object in a_dictionary_name_object_container.items():
                for _key, _value in _dictionary_object.items():
                    print( str(_dictionary_name) +
                           "    " +
                           str(_key) +
                           "  =  " +
                           str(_value) )
        ######
    

    总结:

    • Python 仅将内存地址作为参数传递给函数。
    • 如果名称标识符在当前命名空间中可用,则表示标识符名称的字符串只能通过eval() 函数引用回实际标识符。
    • eval() 函数的假设反转在调用代码未直接“看到”标识符名称的情况下将没有用。例如。在任何被调用的函数中。
    • 目前需要传递给一个函数:
      1. 代表标识符名称的字符串
      2. 实际标识符(内存地址)

    这可以通过同时将'string'eval('string') 传递给被调用函数来实现。我认为这是跨任意函数、模块、名称空间解决这个蛋鸡问题的最“通用”方法,而不使用极端情况解决方案。唯一的缺点是使用了eval() 函数,这很容易导致代码不安全。必须注意不要向eval() 函数提供任何东西,尤其是未经过滤的外部输入数据。

    【讨论】:

    • 这是一篇出色的文章,也是我来这里寻找的优质内容。
    • 如果要获取对象的名称,我们需要在 StackOverflow 上获得 5 页的答案,这在 Python 中有些不对劲。 ://
    • 一个 tl;dr 会很好。
    • TLDR 声明无法实现 OP 的要求。然而,@Alice 的答案和建议使用 locals() 或 globals() 的其他类似答案正是实现了这一点。所以这个 TLDR 具有误导性,这不应该是公认的答案。
    • 有许多语言可以提供这种功能——即使是编译成机器语言的 C/C++ 也可以通过定义; Python 以易于使用的编程入口点而自豪,但缺乏如此流行的工具供人们学习和查看他们的程序在做什么;像 C/C++ 一样,“编译时”函数可以完美地完成这项工作,但似乎所有建议的尝试在 globals() 等中定位变量名的方法都只是部分成功,不能 100% 地工作。匹配是在多个变量可以引用的对象上完成的。
    【解决方案7】:

    Django在生成字段名时不这样做吗?

    http://docs.djangoproject.com/en/dev//topics/db/models/#verbose-field-names

    在我看来是合理的。

    【讨论】:

    • 我认为在 django 模型中,字段是一个类或实例的属性,获取属性名称与将变量名称转换为字符串不同。
    【解决方案8】:

    这适用于简单的数据类型(str、int、float、list 等)

    >>> def my_print(var_str) : 打印 var_str+':', globals()[var_str] >>> a = 5 >>> b = ['你好',',世界!'] >>> my_print('a') 一个:5 >>> my_print('b') b:['你好',',世界!']

    【讨论】:

      【解决方案9】:

      我搜索这个问题是因为我想要一个 Python 程序来打印程序中某些变量的赋值语句。例如,它可能会打印“foo = 3, bar = 21, baz = 432”。打印函数需要字符串形式的变量名。我本可以为我的代码提供字符串“foo”、“bar”和“baz”,但这感觉就像在重复自己。在阅读了之前的答案后,我开发了以下解决方案。

      globals() 函数的行为类似于以变量名(以字符串的形式)作为键的 dict。我想从 globals() 中检索与每个变量的值对应的键。 globals().items() 方法返回一个元组列表;在每个元组中,第一项是变量名(作为字符串),第二项是变量值。我的 variablename() 函数搜索该列表以查找与我需要的字符串形式的变量的值相对应的变量名称。

      函数 itertools.ifilter() 通过使用函数 lambda x: var is globals()[x[0]] 测试 globals().items() 列表中的每个元组来进行搜索。在那个函数中 x 是被测试的元组; x[0] 是变量名(作为字符串),x[1] 是值。 lambda 函数测试被测变量的值是否与传递给 variablename() 的变量的值相同。事实上,通过使用is 运算符,lambda 函数测试被测变量的名称是否与传递给 variablename() 的变量绑定到完全相同的对象。如果是,则元组通过测试并由 ifilter() 返回。

      itertools.ifilter() 函数实际上返回一个迭代器,它在正确调用之前不会返回任何结果。为了正确调用它,我将它放在列表理解 [tpl[0] for tpl ... globals().items())] 中。列表推导只保存变量名tpl[0],忽略变量值。创建的列表包含一个或多个名称(作为字符串),这些名称绑定到传递给 variablename() 的变量的值。

      在下面显示的 variablename() 的使用中,所需的字符串作为列表中的元素返回。在许多情况下,它将是列表中的唯一项目。但是,如果为另一个变量名分配了相同的值,则列表会更长。

      >>> def variablename(var):
      ...     import itertools
      ...     return [tpl[0] for tpl in 
      ...     itertools.ifilter(lambda x: var is x[1], globals().items())]
      ... 
      >>> var = {}
      >>> variablename(var)
      ['var']
      >>> something_else = 3
      >>> variablename(something_else)
      ['something_else']
      >>> yet_another = 3
      >>> variablename(something_else)
      ['yet_another', 'something_else']
      

      【讨论】:

        【解决方案10】:

        我认为这是一个很酷的解决方案,我想你能得到最好的解决方案。但是您是否看到任何处理模棱两可的结果的方法,您的函数可能会返回? 正如"is" operator behaves unexpectedly with integers 所示,相同值的低整数和字符串被python 缓存,因此您的变量名函数可能会以高概率提供模棱两可的结果。 在我的例子中,我想创建一个装饰器,它通过我传递的变量名向一个类添加一个新变量:

        def inject(klass, dependency):
        klass.__dict__["__"+variablename(dependency)]=dependency
        

        但是如果你的方法返回的结果不明确,我怎么知道我添加的变量的名称呢?

        var any_var="myvarcontent"
        var myvar="myvarcontent"
        @inject(myvar)
        class myclasss():
            def myclass_method(self):
                print self.__myvar    #I can not be sure, that this variable will be set...
        

        如果我还要检查本地列表,我至少可以从列表中删除“依赖”变量,但这不是一个可靠的结果。

        【讨论】:

          【解决方案11】:

          只要它是变量而不是第二类,这对我有用:

          def print_var_name(variable):
           for name in globals():
               if eval(name) == variable:
                  print name
          foo = 123
          print_var_name(foo)
          >>>foo
          

          这发生在班级成员身上:

          class xyz:
               def __init__(self):
                   pass
          member = xyz()
          print_var_name(member)
          >>>member
          

          an this for classes(例如):

          abc = xyz
          print_var_name(abc)
          >>>abc
          >>>xyz
          

          所以对于类,它会为您提供名称和属性

          【讨论】:

          • edit您的帖子格式问题。很难理解你在说什么。
          • 很高兴阅读一篇回答问题的帖子,而不是抱怨为什么要问这个问题。
          • 请注意,可以将相同的值绑定到多个名称。在这种情况下,上面的代码将打印多个名称。没有办法知道哪个名字是“正确的”。
          • 使用is variable 而不是== variable ...更安全
          • 不幸的是,这似乎不再适用于 python 3。将print name 更改为print(name) 非常明显,但仍然会出错。 @Erik Aronesty 的修复让它工作了,但@steveha 指出的问题仍然存在。
          【解决方案12】:

          这是一个简洁的变体,可让您指定任何目录。 使用目录查找任何内容的问题是多个变量可以具有相同的值。所以这段代码会返回一个可能的变量列表。

          def varname( var, dir=locals()):
            return [ key for key, val in dir.items() if id( val) == id( var)]
          

          【讨论】:

            【解决方案13】:

            这不是很 Pythonesque,但我很好奇并找到了这个解决方案。您需要复制全局字典,因为它的大小会在您定义新变量后立即更改。

            def var_to_name(var):
                # noinspection PyTypeChecker
                dict_vars = dict(globals().items())
            
                var_string = None
            
                for name in dict_vars.keys():
                    if dict_vars[name] is var:
                        var_string = name
                        break
            
                return var_string
            
            
            if __name__ == "__main__":
                test = 3
                print(f"test = {test}")
                print(f"variable name: {var_to_name(test)}")
            

            返回:

            test = 3
            variable name: test
            

            【讨论】:

            • 您正在查找 globals 字典。这个确切的事情已经在之前的答案中完成,没有创建额外的变量并使用itertools。虽然答案很好,但我认为既然提供了类似的解决方案,您应该对此表示赞同并避免重复。
            【解决方案14】:

            通过使用解包操作符

            >>> def tostr(**kwargs):
                return kwargs
            
            >>> var = {}
            >>> something_else = 3
            >>> tostr(var = var,something_else=something_else)
            {'var' = {},'something_else'=3}
            

            【讨论】:

            • 感谢@restrepo,这正是我创建标准 save_df_to_file() 函数所需要的。为此,我对您的 tostr() 函数进行了一些小改动:` def variabletostr(**df): variablename = list(df.keys())[0] return variablename variabletostr(df=0) ` FYI: I added此代码作为此线程中的新帖子
            【解决方案15】:

            我不知道它是否正确,但它对我有用

            def varname(variable):
                for name in list(globals().keys()):
                    expression = f'id({name})'
                    if id(variable) == eval(expression):
                        return name
            

            【讨论】:

              【解决方案16】:

              以字符串形式获取var的变量名:

              var = 1000
              var_name = [k for k,v in locals().items() if v == var][0] 
              print(var_name) # ---> outputs 'var'
              

              【讨论】:

                【解决方案17】:

                我想指出一个不是反模式的用例,并且没有更好的方法来做到这一点。

                这似乎是python中的一个缺失功能。

                有许多函数,例如 patch.object,采用要修补或访问的方法或属性的名称。

                考虑一下:

                patch.object(obj, "method_name", new_reg)

                当您更改方法的名称时,这可能会启动“假成功”。 IE:你可以发布一个错误,你以为你正在测试......仅仅是因为一个糟糕的方法名称重构。

                现在考虑:varname。这可能是一个高效的内置函数。但是现在它可以通过迭代一个对象或调用者的框架来工作:

                现在你的电话可以是:

                patch.member(obj, obj.method_name, new_reg)

                并且补丁函数可以调用:

                varname(var, obj=obj)

                这将:断言 var 绑定到 obj 并返回成员的名称。或者如果未指定obj,则使用调用者堆栈框架来派生它等。

                在某些时候可以成为一个高效的内置函数,但这里有一个有效的定义。我故意不支持builtins,很容易添加:

                请随意将其粘贴到名为 varname.py 的包中,并在您的 patch.object 调用中使用它:

                patch.object(obj, varname(obj, obj.method_name), new_reg)

                注意:这是为 python 3 编写的。

                import inspect
                
                def _varname_dict(var, dct):
                    key_name = None
                    for key, val in dct.items():
                        if val is var:
                            if key_name is not None:
                                raise NotImplementedError("Duplicate names not supported %s, %s" % (key_name, key))
                            key_name = key
                    return key_name
                
                def _varname_obj(var, obj):
                    key_name = None
                    for key in dir(obj):
                        val = getattr(obj, key)
                        equal = val is var
                        if equal:
                            if key_name is not None:
                                raise NotImplementedError("Duplicate names not supported %s, %s" % (key_name, key))
                            key_name = key
                    return key_name
                
                def varname(var, obj=None):
                    if obj is None:
                        if hasattr(var, "__self__"):
                            return var.__name__
                        caller_frame = inspect.currentframe().f_back
                        try:
                            ret = _varname_dict(var, caller_frame.f_locals)
                        except NameError:
                            ret = _varname_dict(var, caller_frame.f_globals)
                    else:
                        ret = _varname_obj(var, obj)
                    if ret is None:
                        raise NameError("Name not found. (Note: builtins not supported)")
                    return ret
                

                【讨论】:

                  【解决方案18】:

                  完全可以使用 python-varname 包 (python3):

                  from varname import nameof
                  
                  s = 'Hey!'
                  
                  print (nameof(s))
                  

                  输出:

                  s
                  

                  在这里获取包:

                  https://github.com/pwwang/python-varname

                  【讨论】:

                    【解决方案19】:

                    此模块用于将变量名称转换为字符串: https://pypi.org/project/varname/

                    像这样使用它:

                    从变量名导入名称

                    变量=0

                    name=nameof(变量)

                    打印(名称)

                    //输出:变量

                    通过以下方式安装它:

                    pip 安装变量名

                    【讨论】:

                    • 这个包已经提到here。 (顺便说一句:!pip 之前不正确)。
                    • 是的,我注意到它在发布后已经被提及。你是对的'!',我编辑了它。之所以这样,是因为我在笔记本上,如果您在 Jupyter 上,请仅使用“!”。
                    【解决方案20】:

                    感谢@restrepo,这正是我创建标准 save_df_to_file() 函数所需要的。为此,我对您的 tostr() 函数做了一些小改动。希望这对其他人有帮助:

                    def variabletostr(**df):
                            variablename = list(df.keys())[0]
                            return variablename
                        
                        variabletostr(df=0)
                    

                    【讨论】:

                      猜你喜欢
                      • 2011-08-27
                      • 2015-10-25
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2022-08-11
                      • 1970-01-01
                      相关资源
                      最近更新 更多