繁体   English   中英

在python中应用于类实例的方法//在python中将方法应用于类的实例

[英]Method that applies to instance of a class in python // Apply a method to an instance of a class in python

我开始在python中创建类,我对这些术语非常困惑,所以我找不到我的问题的答案,因为我不知道如何问这些,因此这篇文章的双重标题。 我将尝试用以下代码澄清我不知道如何问的问题:

我想在一个简单的类中创建一个方法:

class SimpleClass:
    add(self,Value)
        #Magic goes here

SC=SimpleClass()

该方法应该等同于向类添加新变量:

SC.NewVariableInsideTheClass="test"

但通过一种方法,例如:

SC.NewVariableInsideTheClass.add("test")

在两种情况下“NewVariableInsideTheClass”之前都不存在,我在类中第一次创建该变量。

所以该方法应首先创建非现有实例(我认为这是类中变量的名称),然后将其值设置为“test”,但我真的找不到/搜索如何做到这一点。 。

哪个是我需要的正确问题?

非常感谢你!

-----------------编辑---------------------

好的,所以我想做的是在做的时候得到相同的结果:

SC.NewVariableInsideTheClass.add("test")

在做的时候:

SC.NewVariableInsideTheClass.add("test")

但两者都必须在课外完成,“NewVariableInsideTheClass”是第一次使用! 这里的目标是使用类作为变量存储,例如当第一次使用变量时会发生某些事情,如果它已经存在(以SC.NewVariableInsideTheClass的形式),我将能够以不同的方式使用它。 希望现在更具体一点......

第二次编辑; 原因 - - - - - - - - - - - - -

哇我对你答案的质量和细节印象深刻,我非常感激! 我想知道我想要这个的原因:我正在创建一个简单的python脚本IDE(现在主要用于学习python,nhot有用)。 因此,代码的基础是它在此过程中创建新的变量。 由于程序也将创建函数,我的第一个创建和处理变量的解决方案是在创建的程序全局变量中创建所有变量,并在每个新函数中再次调用它们。 好吧,代码很丑,所以我决定学习并使用一个类,但由于变量在每个程序中都不同,我想要标准化函数创建(即不需要知道它是否是第一个函数,如果它需要初始化任何变量,或者如果它们已经存在),能够: - 在名为变量的列表中存储一个新变量,即使它不存在,也有一个我可以轻松访问的名称-Be能够扩展之前的变量变量将新值作为列表中的新项 - 能够检索这些值所有不使用全局变量,我遇到了这个解决方案。 实际上我修改了你的代码,现在我正在使用你的代码,但不是命名“添加”我命名为“追加”,所以我可以自由地做:

SC.NewVar.append('这是新值')SC.NewVar.append('这是新值')

第一次,它将被创建(因为它不存在),但第二次附加新值,因此,我将能够调用它/播放它或从自动生成的任何其他函数中使用它 - 代码:)

免责声明 :我不知道你为什么要这样做。 如果要使用setattr动态创建属性应该足够:

SC = SimpleClass()
setattr(SC, 'your_new_attribute_name', 'test')

无论如何,有一种简单的方法可以使用帮助程序类获得所需内容:

In [1]: class SimpleClass:
   ...:     def __getattr__(self, attr):
   ...:         return AttributeSetter(self, attr)
   ...: class AttributeSetter:
   ...:     def __init__(self, inst, attr):
   ...:         self._inst = inst
   ...:         self._attr = attr
   ...:     def add(self, value):
   ...:         setattr(self._inst, self._attr, value)
   ...:         

In [2]: SC = SimpleClass()

In [3]: SC.new_attr.add('test')

In [4]: SC.new_attr
Out[4]: 'test'

关于你的评论。 如果您在询问是否可以编写SimpleClass ,那么:

SC.new_attr

返回字符串 'test' 调用Sc.new_attr.add('test')后调用:

SC.new_attr.add('other')

是这样的:

SC.new_attr

现在返回字符串 'other' ,然后答案是: 不,这是不可能的

这是不可能写一个类使得下列不会产生一个AttributeError

In [2]: SC = SimpleClass()

In [3]: SC.new_attr.add('test')
In [4]: SC.new_attr   #this returns a string, not a user-defined class
'test'

In [5]: SC.new_attr.add('new value')
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-5-f218074b7a68> in <module>()
----> 1 SC.new_attr.add('new value')

AttributeError: 'str' object has no attribute 'add'

你为什么要问? 那么,让我们来看看解释器实际上了什么:

In [5]: import dis
   ...: dis.dis(lambda: SC.new_attr.add('some string'))
   ...: 
  2           0 LOAD_GLOBAL              0 (SC) 
              3 LOAD_ATTR                1 (new_attr) 
              6 LOAD_ATTR                2 (add) 
              9 LOAD_CONST               1 ('some string') 
             12 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
             15 RETURN_VALUE 

dis模块允许我们查看解释器正在执行的字节码。 注意有两个 不同的 LOAD_ATTR字节码。 正如您所看到的,解释器首先获取new_attr属性, 然后 ,作为完全独立的操作,它将检索add属性。

现在,类SC只能修改第一个属性访问的行为(即访问new_attr )。 无法知道下一个字节码将访问add ,因此唯一明智的做法是返回已设置的字符串。

以下属性访问( add )是在检索到的值上完成 这意味着解释器会查找字符串的add属性,这显然不存在。

避免此AttributeError的唯一方法是返回一个具有add方法的对象,但这意味着:

In [6]: SC.new_attr
Out[6]: 'test'

失败,因为我们不会返回字符串"test"而是返回另一个对象。

解决这个问题的方法是返回一个具有add方法和value属性的对象,这样我们就可以获得如下内容:

In [12]: SC.new_attr
Out[12]: <__main__.TheClass at 0x7fac44727a90>

In [13]: SC.new_attr.value
Out[13]: 'test'

In [14]: SC.new_attr.add('other')

In [15]: SC.new_attr.value
Out[15]: 'other'

一个不同的解决方案是编写这个类,使其行为像一个字符串(我们甚至可以继承str不执行它!内置的子类化永远不是正确的事情,如果你这样做而不知道确切的话你遇到问题并且很难发现并解决它们的后果,但这意味着代码会变得复杂得多,必须实现字符串支持的所有操作(这意味着实现大约80-90-100个方法! )

让我们使用方法add声明一个ABC类

class ABC(object):
    def add(self, var):
         self.new_var = var

现在添加是实例方法,从而完成你要做的事情,即在实例方法中声明一个实例变量。

 a = ABC()
 # Make an instance
 a.add('test')
 # created a new variable inside instance
 a.new_var
 'test'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM