簡體   English   中英

Python類似C ++的指向類成員的指針

[英]Python analog to C++ pointer to class member

是否可以創建指向Python類成員(而不是方法)的指針?

我想要這樣的東西:

class PClass:
    def __init__(self):
        self.a = 123
    def foo(self, a):
        self.a = a

# this works
def bar(pointer_to_method):
    py_ex = PClass()
    pointer_to_method(py_ex, 321)
bar(PClass.foo)

# this does not
def boo(pointer_to_member):
    py_ex = PClass()
    py_ex.pointer_to_member = 321

boo(PClass.a)

在C ++中,我可以創建類成員和類函數的指針

class CClass
{
public:
    int CClass_property_1;
    int CClass_property_2;
    void CClass_method(const int& param){}
};
auto method_pointer = &CClass::CClass_method;
auto propery_1_pointer = &CClass::CClass_property_1;
propery_1_pointer = &CClass::CClass_property_2;

現在,我可以使用CClass實例從指針調用函數,或訪問屬性。

我對Python類似於C ++的指向類屬性(而不是方法)的指針感興趣

就內存模型和“變量”的真正含義而言,Python與C ++完全不同,因此您的問題沒有任何意義。 我強烈建議您閱讀此書,以了解為什么“指針”這一單純的概念在Python中不適用。

wrt /您的python代碼段:

class PClass:
    def __init__(self):
        self.a = 123
    def foo(self, a):
        self.a = a

# this works
def bar(pointer_to_method):
    py_ex = PClass()
    pointer_to_method(py_ex, 321)

bar(PClass.foo)

之所以PClass.foo ,是因為PClass.foo等於一個未綁定方法(python2.x)或直接等於foo函數(是的,“ function”-cf https://wiki.python.org/moin/FromFunctionToMethod)-但在兩者中一個可調用對象的案例,這些對象既可以是您的函數,也可以是圍繞它的小包裝。

# this does not
def boo(pointer_to_member):
    py_ex = PClass()
    py_ex.pointer_to_member = 321

boo(PClass.a)

這顯然不能工作,原因很明顯,因為a不是PClass類對象的屬性,而是PClass實例的屬性,所以在這里您將得到AttributeError。

現在,即使您嘗試使用quamrana的代碼段(使用PClass實例),也可以通過AttributeError問題,但是代碼仍然無法使用,即:

def boo(pointer_to_member):
    pointer_to_member = 321

instance = PClass()
boo(instance.a)

不會引發錯誤,但仍不會更新instance.a 這里的原因是我鏈接的整篇文章的主題,所以我將不做詳細介紹,但總而言之,python變量只是一個名稱,而不是一個內存地址,因此在上面的代碼中,首先對instance.a進行評估,然后將值(綁定到instance.aint實例boo()以“ pointer_to_member”的名稱傳遞給boo() 此名稱是本地名稱,因此重新綁定它只會影響函數的本地名稱空間,此時,代碼完全不知道instance也不知道它a屬性。

現在,如果您願意在這里解釋您要解決的問題,那么我們當然可以為您提供適當的pythonic解決方案。 關鍵是:嘗試用Python編寫C ++與嘗試用C ++編寫Python一樣無用-不同的語言,不同的習語和模式。

所以Class有方法,但沒有成員? 雖然類的實例兼有?

在Python中,我們說的是“屬性”,而不是“成員”。 是的,類也可以具有屬性(類是ARE對象, type類的實例),但是這些屬性在類的所有實例之間共享。 FWIW,“方法”實際上是類屬性(是的,函數也是對象-實際上,所有內容都是對象,並且它們不存在於不同的名稱空間中)。

同樣,實例本身並不“擁有”方法-方法是類對象的屬性(在C ++ FWIW中實際上也是這種情況)-但是Python的屬性查找規則(在“點分”訪問中調用的代碼)如果在實例本身上找不到該名稱,則在類(及其父級)中查找名稱。 您可以閱讀我鏈接的第二篇文章,以了解有關Python“方法”的真正含義的更多信息(該文章可能需要更新以反映Python3的更改,但除Class.methodname產生的內容外,大部分內容還是准確的)。

看來您正在混合classesinstances Python中的差異比C ++中的差異更明顯。

這是您的代碼的重寫:

class PClass:
    def __init__(self):
        self.a = 123
    def foo(self, a):
        self.a = a


def bar(pointer_to_method):
    pointer_to_method(321)

def boo(pointer_to_member):
    pointer_to_member = 321

instance = PClass()

bar(instance.foo)  # Note that I pass foo bound to instance in the one parameter

boo(instance.a) # Again the member a is bound to instance in the one parameter

在任何時候,不PClass曾經有a成員。 但是,每個PClass實例都有a成員,因為初始化程序會創建一個成員。

更新資料

但是正如@Bruno所指出的,上面的boo函數沒有任何作用,所以也許您想要一些不同的東西:

def zoo(inst, member_name):
    setattr(inst, member_name, 322)

# call like this:
zoo(instance, "a")

它仍然不像C ++那樣pointer-to-member ,但它可能正是您想要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM