1

次のコードを検討してください。

class BaseClass(object):
    def _del_property(attr):
        """Abstract deller"""
        def del_attr(self):
            setattr(self, attr, None)
        return del_attr

    def _set_property(attr):
        """Abstract setter."""
        def set_attr(self, x):
            setattr(self, attr, x)            
        return set_attr

    def _get_property(attr):
        """Abstract getter"""
        def get_attr(self):
            getattr(self, attr)
        return get_attr

    _name = None
    name = property(fget=_get_property('_name'), fset=_set_property('_name'))


class Component(BaseClass):

    _material = None
    material = property(fget=_get_property('_material'), fset=_set_property('_material'), fdel=_del_property('_material'))

_get_property、_set_property、_del_property が継承されないのはなぜですか? どうすれば達成できますか?

これは、同じソース ファイル内の派生クラスだけでなく、このソース ファイルを

from filename import *
4

1 に答える 1

2

クラスを作成すると、新しい名前空間が作成されます。Python はクラス ブロック内のコード ブロックを読み取り、その情報をtype(または対応するメタクラス) に渡します。Componentこの場合、クラスをセットアップするときに_get_propertyがそのスコープ内で定義されていないため、python は不平を言いBaseClass._get_propertyます。

簡単な修正の 1 つは、クラスの名前空間がモジュールの名前空間にアクセスできるため、これらの関数をモジュール レベルの関数にすることです。

def _del_property(attr):
    """Abstract deller"""
    def del_attr(self):
        setattr(self, attr, None)
    return del_attr

def _set_property(attr):
    """Abstract setter."""
    def set_attr(self, x):
        setattr(self, attr, x)            
    return set_attr

def _get_property(attr):
    """Abstract getter"""
    def get_attr(self):
        getattr(self, attr)
    return get_attr


class BaseClass(object):

    _name = None
    name = property(fget=_get_property('_name'), fset=_set_property('_name'))


class Component(BaseClass):

    _material = None
    material = property(fget=_get_property('_material'), fset=_set_property('_material'), fdel=_del_property('_material'))

おそらく、クラスを作成しているときにクラスを見る方がより有益です。

class BaseClass(object):

    def _del_property(attr):
        """Abstract deller"""
        def del_attr(self):
            setattr(self, attr, None)
        return del_attr

    print type(_del_property)
print type(BaseClass._del_property)

これは印刷されます:

<type 'function'>
<type 'instancemethod'>

したがって、内部で通常の関数を扱っていますが、それは魔法の後BaseClassになります。instancemethodtype


個人的には、便利な関数を作成するだけです:

def property_api(name,fget=True,fset=True,fdel=True):
    return property(fget=_get_property(name) if fget else None,
                    fset=_set_property(name) if fset else None,
                    fdel=_del_property(name) if fdel else None)

その後、これを使用できます。本当にしたい場合は、次のように配置することもできBaseClassますstaticmethod

 class BaseClass(object):
      property_api = staticmethod(property_api)

次に、派生クラスは次のようになります。

 class DerivedClass(BaseClass):
      _material = None
      material = BaseClass.property_api('_material')
于 2013-01-30T13:29:41.773 に答える