【问题标题】:Difference between calling a method and accessing an attribute调用方法和访问属性的区别
【发布时间】:2013-06-08 14:23:35
【问题描述】:

我是 Python 的新手,我使用的是 Python 3.3.1。

class Parent: # define parent class 
    parentAttr = 100
    age = 55

    def __init__(self): 
        print ("Calling parent constructor") 

    def setAttr(self, attr): 
        Parent.parentAttr = attr 

class Child(Parent):
    def childMethod(self):
        print ('Calling child method')

现在我将创建

c=child
c.[here every thing will appear methods and attr (age,setAttr)]

如何区分方法和属性?我的意思是,我什么时候使用c.SetAtrr(Argument)c.SetAtrr=value

【问题讨论】:

  • 类文档应该告诉您哪些属性是要调用的方法,哪些是您可以安全更改其值的属性。

标签: python oop


【解决方案1】:

方法也是属性。它们恰好是可调用对象。

您可以使用callable() function 检测对象是否可调用:

>>> def foo(): pass
...
>>> callable(foo)
True
>>> callable(1)
False

调用方法时,查找属性(getattr() 操作),然后调用结果:

c.setAttr(newvalue)

是两个步骤;找到属性(在这种情况下查找类上的属性,并将其视为描述符),然后调用生成的对象,即方法。

当您分配给一个属性时,您将该名称重新绑定到一个新值:

c.setAttr = 'something else'

将是一个setattr() 操作。

如果您想拦截类实例的获取和设置属性,您可以提供attribute access hooks__getattr____setattr____delattr__

如果您想向实例添加方法,则必须将该函数视为descriptor object,它会生成一个方法对象:

>>> class Foo: pass
... 
>>> foo = Foo()  # instance
>>> def bar(self): pass
... 
>>> bar
<function bar at 0x10b85a320>
>>> bar.__get__(foo, Foo)
<bound method Foo.bar of <__main__.Foo instance at 0x10b85b830>>

function.__get__() 的返回值,当给定一个实例和一个类时,是一个绑定方法。调用该方法将调用绑定到实例的self 的底层函数。

说到描述符,property() function 也返回一个描述符,这使得拥有表现类似属性的函数成为可能;他们可以仅针对该属性拦截getattr()setattr()delattr() 操作并将其转换为函数调用:

>>> class Foo:
...     @property
...     def bar(self):
...         return "Hello World!"
... 
>>> foo = Foo()
>>> foo.bar
"Hello World!"

访问.bar 调用了bar 属性get 挂钩,然后调用原始bar 方法。

在几乎所有情况下,您都不需要callable() 函数;您记录您的 API,并提供方法和属性,并且您的 API 的用户会弄清楚它,而无需测试每个属性以查看它是否可调用。使用属性,您可以灵活地提供在任何情况下都可以调用的属性。

【讨论】:

  • 那么 .. 我可以使用 c.SetAtrr=value 和 c.SetAtrr(Value) 吗,它们会一样吗??
  • @disasterromio:不,一个是设置属性,一个是调用函数。
  • 感谢您抽出宝贵时间,您最好先检查对象是否可调用?
  • @D007a:但你的目标是什么?通常,这取决于文档,不是吗?该类的用户一次了解您的 API 是什么,您通常不需要检测某些内容是否可调用。
猜你喜欢
  • 2010-11-21
  • 1970-01-01
  • 2012-08-30
  • 2011-02-02
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 2020-12-14
  • 1970-01-01
相关资源
最近更新 更多