Python装饰一个类以更改父对象类型 [英] Python decorate a class to change parent object type

查看:146
本文介绍了Python装饰一个类以更改父对象类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有两个类X& Y.您想通过向类添加属性来装饰这些类,以产生新的类X1和Y1.

Suppose you have two classes X & Y. You want to decorate those classes by adding attributes to the class to produce new classes X1 and Y1.

例如:

class X1(X):
  new_attribute = 'something'

class Y1(Y):
  new_attribute = 'something'

对于X1和Y1,

new_attribute 始终相同. X& Y没有任何有意义的关系,除了不可能多重继承.还有一组其他属性,但这只是为了说明而已.

new_attribute will always be the same for both X1 and Y1. X & Y are not related in any meaningful way, except that multiple inheritance is not possible. There are a set of other attributes as well, but this is degenerate to illustrate.

我觉得这太复杂了,但是我曾想过使用装饰器,就像这样:

I feel like I'm overcomplicating this, but I had thought to use a decorator, somewhat likeso:

def _xywrap(cls):
  class _xy(cls):
    new_attribute = 'something'
  return _xy

@_xywrap(X)
class X1():
   pass

@_xywrap(Y)
class Y1():
   pass

感觉好像我错过了一个相当普遍的模式,并且我非常想念,输入和反馈.

It feels like I'm missing a fairly common pattern, and I'd be much obliged for thoughts, input and feedback.

感谢您的阅读.

布莱恩

示例:

以下是可能有启发性的相关摘录.常见的类如下:

Here is a relevant extract that may illuminate. The common classes are as follows:

from google.appengine.ext import db

# I'm including PermittedUserProperty because it may have pertinent side-effects
# (albeit unlikely), which is documented here: [How can you limit access to a
# GAE instance to the current user][1].

class _AccessBase:
   users_permitted = PermittedUserProperty()
   owner = db.ReferenceProperty(User)

class AccessModel(db.Model, _AccessBase):
    pass

class AccessExpando(db.Expando, _AccessBase):
    pass

# the order of _AccessBase/db.* doesn't seem to resolve the issue
class AccessPolyModel(_AccessBase, polymodel.PolyModel):
    pass

这是子文档:

 class Thing(AccessExpando):
     it = db.StringProperty()

有时候,事物将具有以下属性:

Sometimes Thing will have the following properties:

 Thing { it: ... }

其他时间:

 Thing { it: ..., users_permitted:..., owner:... }

我一直无法弄清为什么Thing有时会具有_AccessParent属性,而有时候却没有.

I've been unable to figure out why Thing would sometimes have its _AccessParent properties, and other times not.

推荐答案

使用3个参数正如您推测的那样,这的确是一个相当流行的习惯用法.

This is indeed, as you surmised, a reasonably popular idiom.

编辑:在一般情况下,如果某类具有自定义元类,则可能需要提取并使用它(带有1个自变量type)来代替type本身,以保留(您的Django和App Engine模型可能就是这种情况):

Edit: in the general case if someclass has a custom metaclass you may need to extract and use it (with a 1-argument type) in lieu of type itself, to preserve it (this may be the case for your Django and App Engine models):

def makeSomeNicelyDecoratedSubclass(someclass):
  mcl = type(someclass)
  return mcl('MyNiceName', (someclass,), {'new_attribute':'something'})

这在上面的简单版本也可以使用(因为在简单情况下,没有自定义元类type(someclass) is type).

This also works where the simpler version above does (since in simple cases w/no custom metaclasses type(someclass) is type).

这篇关于Python装饰一个类以更改父对象类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆