2011-05-16 32 views
3

如何在Python中模擬賦值運算符重載?例如...如何在Python中模擬賦值運算符重載?

class Example(object): 

    name = String() 
    age = Integer() 

    def __init__(self,myname,myage): 
     self.name.value = myname 
     self.age.value = myage 

,而不是做self.name.value =名字,你怎麼可以模擬賦值運算符超載使MYNAME分配,當你做self.name.value self.name =我的名字?

+0

我結束了創建一個元類註冊類型的屬性(這是'Property'類的子類)。然後我重載'Example'('Model')類中的'__setattr__'方法來類型檢查元類註冊的屬性。見https://github.com/espeed/bulbs/blob/master/bulbs/model.py – espeed 2013-02-02 06:51:22

+0

你在使用'traits'嗎? – pradyunsg 2013-10-18 18:30:44

+0

不,我推出了我自己的Property類class https://github.com/espeed/bulbs/blob/master/bulbs/property.py,它是Model的元類使用的。查看燈泡模型API文檔http://bulbflow.com/docs/api/bulbs/model/ – espeed 2013-11-18 18:13:07

回答

0

我最終創建了一個名爲ModelMeta的Model元類來註冊類型化的屬性。

http://github.com/espeed/bulbs/blob/master/bulbs/model.py

在這種情況下,該類型的屬性是圖形數據庫「屬性」,這是房產類的子類。

https://github.com/espeed/bulbs/blob/master/bulbs/property.py

下面是一個例子模型聲明:

# people.py 

from bulbs.model import Node, Relationship 
from bulbs.property import String, Integer, DateTime 
from bulbs.utils import current_datetime 

class Person(Node): 

    element_type = "person" 

    name = String(nullable=False) 
    age = Integer() 


class Knows(Relationship): 

    label = "knows" 

    created = DateTime(default=current_datetime, nullable=False) 

用法示例:

>>> from people import Person 
>>> from bulbs.neo4jserver import Graph 
>>> g = Graph() 

# Add a "people" proxy to the Graph object for the Person model: 
>>> g.add_proxy("people", Person) 

# Use it to create a Person node, which also saves it in the database: 
>>> james = g.people.create(name="James") 
>>> james.eid 
3 
>>> james.name 
'James' 

# Get the node (again) from the database by its element ID: 
>>> james = g.people.get(james.eid) 

# Update the node and save it in the database: 
>>> james.age = 34 
>>> james.save() 

# Lookup people using the Person model's primary index: 
>>> nodes = g.people.index.lookup(name="James") 

見...

2

你不能超載在Python賦值運算符但是與魔術方法的一些聰明的重載,你可以通過重載RSHIFT魔術方法,對蟒蛇的綜合指南的魔術方法看this得到一個< < = B + C 。

13

在這個非常特殊的情況下,在屬性分配中,您可以使用descriptor。事實上,我懷疑在你使用的例子中,IntegerString實際上是描述符。

除了使用預製描述符,使用描述符最簡單的方法是使用property()。這裏有一個簡單的例子:

>>> class Foo(object): 
     @property 
     def bar(self): 
      print 'bar' 
      return 'bar' 
     @bar.setter 
     def bar(self, value): 
      print 'bar =', value 


>>> afoo = Foo() 
>>> afoo.bar 
bar 
'bar' 
>>> afoo.bar = 'baz' 
bar = baz 
>>> 
+0

是的,這可能工作。我用__get __(),__set __()和to_db()方法創建了一個類String();然而,當我做name = String()時,我不能做self.name.to_db(),因爲它調用了__get __()返回的值的to_db(),而不是對象「name」。解決這個問題的一種方法是不直接調用self.name.to_db(),而是在實例中設置一個標誌,並在__get __()中創建一個條件來檢查它,如果它是True,則調用to_db(),但這看起來很奇怪。有沒有更好的辦法? – espeed 2011-05-16 20:28:47

+0

如果您希望能夠執行'self.attr1.attr2',您可能不需要'attr1'的描述符。首先,每個實例通常沒有一個描述符,每個類都有一個描述符,所以在獲取每個實例信息時必須要付出很大的麻煩。描述符通常用於隱藏像數據庫持久性這樣的實現細節。相反,您應該根據描述符特殊的方法名稱來實現完整的功能,並且可能還需要父級的元類。 – SingleNegationElimination 2011-05-17 01:59:42

0

您不能重載分配。它不是運營商。只需在對象構造函數中構造值就可以了。

class Example(object): 

    def __init__(self,myname, myage): 
     self.name = String(myname) 
     self.age = Integer(myage) 

然而,在這種情況下,我不明白爲什麼你不能只使用內置strint