如何在Python中模拟赋值运算符重载?

3
如何在Python中模拟赋值运算符重载?例如...
class Example(object):

    name = String()
    age = Integer()

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

不要使用 self.name.value = name 的方法,如何模拟赋值运算符的重载,以便在执行 self.name = myname 时将 myname 赋值给 self.name.value?


我最终创建了一个元类来注册类型属性(这些属性都是Property类的子类)。然后我在ExampleModel)类中重载了__setattr__方法,以对由元类注册的这些属性进行类型检查。请参见https://github.com/espeed/bulbs/blob/master/bulbs/model.py。 - espeed
你是否正在使用traits - pradyunsg
不,我自己编写了 Property 类 https://github.com/espeed/bulbs/blob/master/bulbs/property.py ,这是模型元类使用的。请参阅 Bulbs 模型 API 文档 http://bulbflow.com/docs/api/bulbs/model/。 - espeed
请查看Enthought的traits库。(它有更多支持其他内容的东西)。另外,您需要的是描述符。那里有一个关于相同内容的示例。 - pradyunsg
4个回答

13
在这个特殊的情况下,在属性赋值中,您可以使用描述符。实际上,我怀疑在您使用的示例中,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
>>> 

是的,那可能行得通。我创建了一个带有__get__()、set()和一个to_db()方法的String()类;但是,当我执行name = String()时,我无法执行self.name.to_db(),因为它在__get__()返回的值上调用了to_db(),而不是对象"name"上。处理这个问题的一种方法是不直接调用self.name.to_db(),而是在实例中设置一个标志,并在__get__()中创建一个条件来检查它并在其为True时调用to_db(),但这似乎很笨拙。有更好的方法吗? - espeed
如果你想要能够执行 self.attr1.attr2,那么你可能不想要一个针对 attr1 的描述器。首先,通常情况下你不会为每个实例都有一个描述器,而是每个类只有一个,因此你需要花费很多精力来获取每个实例的信息。描述器主要用于隐藏实现细节,例如数据库持久性。相反,你应该通过描述器特殊方法名和父类上的元类来实现完整功能。 - SingleNegationElimination

2

在Python中,你不能重载赋值运算符,但是通过巧妙地重载魔术方法,你可以实现A <<= B+C。具体的,可以通过重载rshift魔术方法来实现。想要了解更多关于Python魔术方法的内容,请参考这个全面的指南。


0

你不能重载赋值运算符,因为它不是一个运算符。在对象构造函数中构造值会更好。

class Example(object):

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

然而在这种情况下,我不明白为什么你不能只使用内置的strint


0

我最终创建了一个名为ModelMeta的模型元类,用于注册类型属性。

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

在这种情况下,类型属性是图形数据库“属性”,它们都是Property类的子类。

请参见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")

请见...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接