Python中的空类对象

62

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

class Employee:
    pass

这个例子接着定义了一个该类的对象的名称和其他属性:

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

有趣!

我想知道是否有一种方法可以像这样为类的一个实例动态定义一个函数?例如:

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

在我的Python解释器中这个不起作用,但是是否有其他方法可以做到呢?


1
可能吗?是的。一个好主意吗?很少(当然除了一些元编程)。 - user395760
4个回答

50
一个类更或多或少是一个对象的属性字典的华丽封装。当你实例化一个类时,你可以给它的属性赋值,这些值将被存储在foo.__dict__中;同样地,你可以在foo.__dict__中查找任何你已经写过的属性。
这意味着你可以做一些很酷的动态事情,比如:
class Employee: pass
def foo(self): pass
Employee.foo = foo

还可以分配给特定的实例。(编辑:添加了self参数)


19

尝试使用lambda

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

你将能够做到以下几点:

john.greet()

编辑: 感谢Thomas K的提醒 - 这在Python 3.2上有效,而在Python2中不行,因为print被视为语句。但是这将适用于没有语句lambda(对吗?抱歉,我只了解python3.2(:)


2
这实际上不起作用:lambda不能包含语句。 - Katriel
@katrielalex - 在我的Python 3.2上完美运行(当然,需要为“print”添加括号)。什么语句? - Kiril Kirov
1
@Kirii: 在Python 2中,print是一个语句。你现在添加括号是因为在Python 3中它变成了一个函数。 - Thomas K
@Thomas K - 啊,谢谢!我不知道print在Python2中是一个语句。 - Kiril Kirov
2
由于 OP 想要动态定义一个函数,也许 print 的例子并不是最好的。+1 - Eric Wilson

1
您还可以使用标准模块collection中的“命名元组”。命名元组类似于“普通”元组,但元素具有名称,并且可以使用“点语法”访问元素。来自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)

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 

在其他情况下也很有用 - 比如当您需要访问字典键的属性时。


1
肯定的,依赖之神需要更多的依赖项。 - iperov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接