2013-07-16 93 views
1

我开始在python中创建类,我对这些术语感到困惑,所以我找不到我的问题的答案,因为我不知道如何问这些,因此这个职位的双重标题。我会尝试澄清,我不知道如何提出用下面的代码的问题:适用于python中类的实例的方法//将方法应用于python中的类的实例

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

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

SC=SimpleClass() 

的方法应该是相当于增加一个新的变量到类:

SC.NewVariableInsideTheClass="test" 

但是通过一种方法,例如:

SC.NewVariableInsideTheClass.add("test") 

在这两种情况下,“NewVariableInsideTheClass”之前都不存在,我在课堂内首次创建该变量。因此,该方法应该首先创建一个不存在的实例(我认为这是一个类中的变量的名称),然后将其值设置为“测试”,但我真的找不到/如何搜索这样做...

这将是正确的问题,我需要什么?

非常感谢!

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

好的,如此我想要做的是得到相同的结果时做:

SC.NewVariableInsideTheClass.add("test") 

,做的时候:

SC.NewVariableInsideTheClass.add("test") 

但是它们都必须在类外进行,以“NewVariableInsideTheClass”正在使用的第一次!这里的目标是将类用作变量存储,例如当第一次使用变量时会发生什么,如果它已经存在(以SC.NewVariableInsideTheClass的形式),我将能够以不同的方式使用它。 希望这个更具体一些...

SECOND EDIT;原因为什么-------------------------

哇你的回答质量和细节印象深刻,我非常感谢!像你一样知道我为什么要这样做的原因:我正在创建一个简单的Python脚本IDE(现在主要是用于学习Python,有用的话)。所以代码的基础是它会一路创建新的变量。由于程序也会创建函数,因此创建和处理变量的第一个解决方案是将创建的程序中的所有变量全局化,并在每个新函数中再次调用它们。那么代码是丑陋的,所以我决定学习和使用一个类,但是因为变量在每个程序中都有所不同,所以我想要标准化函数创建(即不需要知道它的第一个函数是否需要初始化变量,或者它们已经存在),方法是: - 在一个名为变量的列表中存储一个新变量(即使该列表不存在,并且可以轻松访问该变量的名称) - 能够扩展前一个变量的新值作为列表中的新项目 - 能够检索这些值 所有未使用全局变量的情况下,我遇到了此解决方案。其实我修改了你的代码,现在我正在使用你的代码,而不是命名为“add”,我将其命名为“append”,所以我可以自由地做:

SC.NewVar.append('This is new value') (这是新值)

第一次,它将被创建(因为它不存在),但第二次新值被追加,因此,我将能够称它为/玩它或在自动生成的代码:)

+0

您是否正在尝试完成动态变量的创建?这个问题的目的是什么,它非常模糊.. –

+0

你能解释一下你为什么要这样做吗?这可能是可能的,但它打破了一些关于Python如何工作的预期。 –

+0

是的,即时通讯抱歉的模糊,但我从字面上不知道如何问它,我要去评论答案,并指定更多 –

回答

4

免责声明:我不知道你为什么要这么做。如果要动态地创建使用属性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使得:

'test' 调用 Sc.new_attr.add('test')电话
SC.new_attr 

回报:

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个方法!)

+0

非常感谢。我还有一个问题,有没有办法,如果你做两次“SC.new_attr.add('test')”它只会重新设置new_attr值'test',而不是尝试将值设置为海峡? –

+0

@Iwantbadges更新。简短的回答*你不能*做到你想要的。另外,我想强调一下:*你想要做的事情真的很糟糕**代码实践*。可以尝试这个东西来知道你可以做什么,不能在python中做什么,但是*不要在任何项目/产品代码中使用它*! – Bakuriu

+0

解释为什么我需要编辑问题 –

0

允许声明使用它从任何其他函数的方法的类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' 
+0

好吧,非常感谢你,这是一个开始,但我忘记解释得很好:我希望“new_var”是一个动态名称,不是在类中声明的,而是在其外部声明的,并且直接通过调用它, –