2011-06-01 106 views
39

我教的面向對象編程和我在如何解釋類​​刷牙蟒蛇上課,我看到了一個空的類定義:蟒蛇空類對象

class Employee: 
    pass 

的例子然後繼續定義該類別的對象的名稱和其他屬性:

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

有趣!

我想知道是否有辦法爲這樣的類動態定義一個函數?像這樣:

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

這不適用於我的python解釋器,但是有沒有另一種方法呢?

+1

可能嗎?是。一個好主意?很少(當然,在一些元編程之外)。 – delnan 2011-06-01 16:43:54

+3

我見過的最短的空類定義來自http://www.gossamer-threads.com/lists/python/python/832915#832915:Employee = type('Employee',(),{})'然後'john = Employee()'等 – eudoxos 2015-06-03 09:18:50

回答

30

類是或多或少的屬性對象dict看中包裝當你實例化一個類。您可以分配給它的屬性,以及那些將被存儲在foo.__dict__;同樣,你可以看看在foo.__dict__你已經寫好的任何屬性

這意味着你可以做一些巧妙的動態的東西,如:

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

以及分配給特定的實例。 (編輯:添加self參數)

+7

你的例子不會按預期工作:'john.foo()'會引發一個'TypeError',因爲沒有'self'參數'。把一個函數放到一個類中會變成一個方法,所以它需要一個'self'。另一方面,如果你給一個實例分配一個函數,它仍然是一個函數,並且不能訪問實例'self',這通常是無用的。 – 2011-06-01 16:15:24

+0

@Jochen:你當然是對的。 TA!對於OP來說:如果你明白出了什麼問題,爲什麼會修復它,這可能會有所幫助! – katrielalex 2011-06-01 16:36:31

+0

@Jochen,謝謝你爲此添加了一些顏色。如果被定義的函數只是對象特定的(我認爲),訪問「自我」有多重要/有用。換句話說,這個函數並沒有爲Employee類型的所有對象定義(除非你使用@ katrielalex的例子並且使用ClassName來定義它),但是僅限於類的實例(就像我在OP中的「john」例子中那樣) – Ramy 2011-06-01 16:41:04

15

嘗試用lambda

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

的,你就可以做到:

john.greet() 

編輯:謝謝托馬斯ķ的注意 - 這個工程上Python 3.2而不是Python2,其中print看起來是statement 。但是,這會爲lambda的工作,沒有聲明(右對不起,我只知道python3.2(?)

+1

這實際上並不起作用:lambda表達式不能包含語句。 – katrielalex 2011-06-01 15:58:21

+0

@katrielalex - 在我的python 3.2上完美工作(當然,在'print'中添加了括號)。什麼說法? – 2011-06-01 16:00:00

+0

在PRE python 3.x中不起作用 – Ramy 2011-06-01 16:05:30

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 

這是在其他情況下太有用 - 當你需要的屬性訪問字典鍵,如。

0

您也可以使用collection標準模塊中的「命名元組」。命名元組像「普通」元組一樣工作,但元素具有名稱,您可以使用「點語法」訪問元素。來自collection docs

>>> # 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)