對於遞歸函數,我們可以這樣做:蟒蛇:如何引用的類從它內部(如遞歸函數)
def f(i):
if i<0: return
print i
f(i-1)
f(10)
但是有沒有辦法做以下的事情嗎?
class A:
# do something
some_func(A)
# ...
對於遞歸函數,我們可以這樣做:蟒蛇:如何引用的類從它內部(如遞歸函數)
def f(i):
if i<0: return
print i
f(i-1)
f(10)
但是有沒有辦法做以下的事情嗎?
class A:
# do something
some_func(A)
# ...
如果你想指的是同一個對象,只是用「自我」:
class A:
def some_func(self):
another_func(self)
如果你想創建相同類的新對象,只要做到這一點:
class A:
def some_func(self):
foo = A()
如果你想有機會獲得
元類
類對象(最有可能不是你想要的),再一次,只是做:
class A:
def some_func(self):
another_func(A) # note that it reads A, not A()
只是一個澄清:在你的最後一個例子中,引用「A」被稱爲「類對象」,而不是「元類」,這是一個完全不同的概念。在你的例子中A的元類將是'類型。ClassType'(或'type',如果使用新式類或python3) – Crast 2010-01-09 23:55:20
該類中的大部分代碼都在方法定義內,在這種情況下,您可以簡單地使用名稱A
。
-1他非常具體地詢問在類的主體中調用A,而不是從它的方法中調用A. – 2010-01-10 02:53:08
你想實現什麼?可以使用元類訪問類來調整其定義,但不推薦使用它。
您的代碼示例可以簡單地寫爲:
class A(object):
pass
some_func(A)
沒有辦法做到這一點的類範圍內,不除非A被定義爲別的第一(然後some_func(A )會做一些與你期望的完全不同的東西)
除非你正在做某種類型的堆棧檢查來向類中添加位,否則爲什麼你會這樣做。爲什麼不只是:
class A:
# do something
pass
some_func(A)
也就是說,在A之後運行some_func。或者,如果您想以某種方式修改類A,則可以使用類裝飾器(它在2.6中添加的語法)或元類。你能否澄清你的用例?
沒有。它在一個函數中工作,因爲函數內容是在調用時執行的。但是課程內容是在定義時間執行的,此時課程還不存在。
它通常不是問題,因爲你可以定義後攻入進一步成員到類,這樣你就可以定義一個類分成多個部分:
class A(object):
spam= 1
some_func(A)
A.eggs= 2
def _A_scramble(self):
self.spam=self.eggs= 0
A.scramble= _A_scramble
它,然而,相當不尋常的希望在自己定義的中間調用類的函數。目前還不清楚你想要做什麼,但有機會,你會更好用decorators(或相對較新的class decorators)。
如果它實際上在範圍內,那麼可以在其正文內引用該類的名稱(如內部方法定義);如果它在頂層定義,它會是什麼。 (在其他情況下可能不會,由於Python範圍的怪癖!)。
有關作用域疑難雜症的插圖,嘗試實例富:
class Foo(object):
class Bar(object):
def __init__(self):
self.baz = Bar.baz
baz = 15
def __init__(self):
self.bar = Foo.Bar()
(這將抱怨全局名稱「欄」沒有被定義)
而且,東西告訴我你可能想看看類方法:docs on the classmethod function(用作裝飾器),a relevant SO question。 編輯:好的,所以這個建議可能根本不適合......這只是我在閱讀你的問題時想到的第一件事情,就像替代構造函數等。如果更簡單的東西適合你的需求,請避開@classmethod
怪異。 :-)
你不能用你描述的特定語法來評估它們。示例函數給出的原因是函數體內調用f(i-1)是因爲名稱分辨率爲f直到實際調用該函數纔會執行。此時f存在於執行範圍內,因爲該函數已經被評估。在類示例的情況下,在類定義仍在評估期間,會查找對類名的引用。因此,它在當地範圍內還不存在。
備選地,期望的行爲可以使用元類像這樣來完成:
class MetaA(type):
def __init__(cls):
some_func(cls)
class A(object):
__metaclass__=MetaA
# do something
# ...
使用這種方法可以在該類被評估時執行的類對象上的任意操作。
這是解釋*爲什麼不能完成的唯一答案(函數體不是僅僅根據定義來執行,而是類體)。感謝您的澄清。 – Dubslow 2017-10-30 08:37:06
如果你想要做的一點點事情哈克做
class A(object):
...
some_func(A)
如果你想要做一些更復雜,你可以使用元類。元類負責在完全創建之前操作類對象。模板應該是:
class AType(type):
def __new__(meta, name, bases, dct):
cls = super(AType, meta).__new__(meta, name, bases, dct)
some_func(cls)
return cls
class A(object):
__metaclass__ = AType
...
type
是默認的元類。元類的實例是類,因此__new__
返回(在本例中)A
的修改實例。
有關元類的更多信息,請參閱http://docs.python.org/reference/datamodel.html#customizing-class-creation。
在Python中,您不能在類體中引用該類,儘管在像Ruby這樣的語言中您可以這樣做。
在Python中,您可以使用類裝飾器,但一旦類初始化後就會調用它。另一種方法可能是使用元類,但它取決於你想要實現的。
爲什麼?在這方面,什麼使得類定義體與函數體不同?鑑於函數和類都是頭等對象,他們身體的差異對我而言並不是很明顯。 編輯:正如下面的另一個答案指出的那樣,函數體不是在執行定義本身時執行的,而類體是作爲類定義執行的一部分執行的。 – Dubslow 2017-10-30 08:33:09
你如何使用類裝飾器和元類來實現這一點?一個例子會很棒。 – 2017-12-17 10:56:04
不清楚你想要什麼或意思。 'A類:'不會創建一個對象,所以沒有'A'來引用。請參閱爲可能的事情提供的解決方案,你可能意味着... – 2010-01-09 23:50:28
@Andrew __class A:__創建一個_class object_作爲Python中的類是第一類 – 2010-01-10 02:00:48