2011-05-16 71 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