56

我正在教授一个关于面向对象编程的 Python 课程,当我在复习如何解释类​​时,我看到了一个空的类定义:

class Employee:
    pass

然后该示例继续为此类的对象定义名称和其他属性:

john = Employee()
john.full_name = "john doe"

有趣的!

我想知道是否有办法为这样的类的实例动态定义函数?就像是:

john.greet() = print 'Hello, World!'

这在我的 Python 解释器中不起作用,但是还有另一种方法吗?

4

4 回答 4

46

类或多或少是dict对象属性的一个精美包装器。当您实例化一个类时,您可以分配给它的属性,这些属性将存储在foo.__dict__; 同样,您可以查看foo.__dict__您已经编写的任何属性。

这意味着您可以执行一些简洁的动态操作,例如:

class Employee: pass
def foo(self): pass
Employee.foo = foo

以及分配给特定实例。(编辑:添加self参数)

于 2011-06-01T15:57:29.943 回答
18

尝试lambda

john.greet = lambda : print( 'hello world!' )

你将能够做到:

john.greet()

编辑:感谢Thomas K的注释 - 这适用于Python 3.2Python2,而不是 Python2,print似乎是statement。但这适用于lambdas,没有语句(对吗?对不起,我只知道python3.2(: )

于 2011-06-01T15:52:15.190 回答
1

您还可以使用collection标准模块中的“命名元组”。命名元组像“普通”元组一样工作,但元素有名称,您可以使用“点语法”访问元素。从集合文档

>>> # Basic example
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(11, y=22)     # instantiate with positional or keyword arguments
>>> p[0] + p[1]             # indexable like the plain tuple (11, 22)
33
>>> x, y = p                # unpack like a regular tuple
>>> x, y
(11, 22)
>>> p.x + p.y               # fields also accessible by name
33
>>> p                       # readable __repr__ with a name=value style
Point(x=11, y=22)
于 2016-09-08T12:20:53.070 回答
0

你可以使用 AttrDict

>>> from attrdict import AttrDict
>>> my_object = AttrDict()
>>> my_object.my_attribute = 'blah'
>>> print my_object.my_attribute
blah
>>> 

从 PyPI 安装 attrdict:

pip install attrdict 

它在其他情况下也很有用——比如当您需要对 dict 键进行属性访问时。

于 2015-02-24T17:53:59.427 回答