实例属性可以在Python中调用实例类方法吗?

时间:2018-03-30 16:19:02

标签: python class methods attributes instance

Python noob在这里,尝试更多地使用类,并将我的代码分解为一个更简单的例子来说明我正在使用的内容:

假设我有一个类,其实例和属性与该实例相关联

class Foo(object):
    def __init__(self, attribute=None):
        self.attribute = attribute

    def dosomething(self):
        print('I did a thing!')

a = Foo()
a.attribute='bar'

现在,从实例运行方法' a'按预期工作

a.dosomething()

输出:

I did a thing!

但是,尝试从' a'的属性调用该方法。导致错误

a.attribute='bar'
a.attribute.dosomething()
AttributeError: 'str' object has no attribute 'dosomething'

这会导致属性错误,这是预期的。 ' a.attribute'不再是类型的“Foo”类型。而是一种类型的' str。我的问题是,我可以在类中做些什么来允许属性使用类方法吗?

此外,由于我在我的互联网搜索期间没有找到任何结果,我假设它可能不推荐,可能不是pythonic? (只是一个猜测)。我愿意接受如何使其更好的建议,但理想情况下,我希望保持属性的方式,同时仍然可以调用类方法。类的属性的点语法确实有助于我保持组织有序,但如果它不能调用它所源自的类中的方法,那对我来说就没用了。

提前致谢!

3 个答案:

答案 0 :(得分:0)

不,这不起作用。如果你理解了课程的运作方式,那真的没有意义。

a.attribute只是字符串'bar'的名称。该字符串对a一无所知,也不应该。 1 同一个字符串可能有很多其他名称。例如:

>>> bar = 'bar'
>>> a.attribute = bar
>>> bar.dosomething()
AttributeError: 'str' object has no attribute 'dosomething'

这正是你所期待的,对吧?但...

>>> a.attribute is bar
True

由于bara.attribute是同一个对象,因此显然必须做同样的事情:

>>> a.attribute.dosomething()
AttributeError: 'str' object has no attribute 'dosomething'

<子> 1。有一些特殊情况下这样的东西会有用,但它们是通过让属性只是一个字符串来解决的,而是某种类似于字符串的智能对象但也知道它的类,实例或父类。有关示例,请参阅stdlib中的enum模块 - 然后单击source code链接以查看其实现方式。

答案 1 :(得分:0)

在此示例中,当您执行a.attribute='bar'时,属性是一个字符串,因此如果您要type(a.attribute),它将返回string。因此,Python正在dosomething()类中查找属性str而未找到它。

答案 2 :(得分:0)

你似乎想要做的事情并没有多大意义。猜测一下,似乎你把与继承相关的一些概念与你对成员参考的python点语法的理解混为一谈,当它们彼此无关时。

你写了

  

'a.attribute'不再是'Foo'的类类型,而是'str'的类类型。

这表明对正在发生的事情存在根本性的误解。没有状态发生变化 - a仍然是a类型的实例Foo。它有一个成员attribute,这是一个字符串。表达式a.attribute仅仅是指向该字符串。如果您需要在a上调用某个方法,您仍然可以在a.attribute上尝试调用它的任何地方执行此操作:

>>> a.attribute = 'bar'
>>> a.doSomething()
I did a thing!

一种类型的对象调用未在其类中定义的方法的常见场景是继承

class Foo(object):
  def superclass_method(self):
    print "Hi"

class Bar(Foo):
  pass

b = Bar()
b.superclass_method() # prints "Hi"

在这种情况下,我们说b,Bar的实例,也是 Foo。因此,Foo定义的任何方法,Bar实例都可以访问。

如果你告诉我们一些你想要完成的事情,我可以更具体地说明你是否以及如何使用继承。但点符号只是谈论附加到对象的值的一种方式。它实际上只是在左侧对象的字典中查找与右侧名称相关联的值 - foo.bar等同于getattr(foo, 'bar')