2017-12-29 18 views
1

.__クラスで参照することなく、クラスにmember_descriptorをバインドします:どのように私は私の民営化のトリックはIDLEとのpython3のREPLの両方で動作するのでdict__に

>>> class A(object): 
...  __slots__ = ['attr'] 
... 
>>> dscget = A.__dict__['attr'].__get__ 
>>> dscset = A.__dict__['attr'].__set__ 
>>> del A.attr 
>>> 

ではなく、かなり私のプログラムで(同じ正確なセットアップと力学)

Python 3.4.3 |Anaconda 2.3.0 (32-bit)| (default, Mar 6 2015, 12:08:17) [MSC v.1600 32 bit (Intel)] on win32 
Type "copyright", "credits" or "license()" for more information. 
>>> ================================ RESTART ================================ 
>>> 
Traceback (most recent call last): 
    File "\home\tcll\Projects\python\UGE\test_FORMAT.py", line 5, in <module> 
    import API 
    File "\home\tcll\Projects\python\UGE\API\__init__.py", line 43, in <module> 
    from . import CONST, OBJECT 
    File "\home\tcll\Projects\python\UGE\API\OBJECT\__init__.py", line 191, in <module> 
    from ._collection import * 
    File "\home\tcll\Projects\python\UGE\API\OBJECT\_collection.py", line 209, in <module> 
    private() 
    File "\home\tcll\Projects\python\UGE\API\OBJECT\_collection.py", line 187, in private 
    getbase,  setbase   = getset(UGECollection, '__base__');   del UGECollection.__base__ 
AttributeError: readonly attribute 
>>> 

私は読み取り専用でそれらを上書きするだけで、これは実際に、彼らは属性を削除しないのに負荷は、最初の2クラスは、実際に、問題なく期待通りに動作し、負荷のことを第三級であることに注意すべきですプロパティ。

member_descriptorがどのように初期化され、クラスに登録されているかを知りたいので、クラスdictの参照を必要とせずに作成することができます。

member_descriptor名を容易に得ることができますが、インスタンスの作成は非常に困難であると考えられる:

>>> class A(object): 
...  __slots__ = ['attr'] 
... 
>>> member_descriptor = A.attr.__class__ 
>>> member_descriptor() 
Traceback (most recent call last): 
    File "<pyshell#3>", line 1, in <module> 
    member_descriptor() 
TypeError: cannot create 'member_descriptor' instances 
>>> member_descriptor.__new__(member_descriptor) 
Traceback (most recent call last): 
    File "<pyshell#4>", line 1, in <module> 
    member_descriptor.__new__(member_descriptor) 
TypeError: object.__new__(member_descriptor) is not safe, use member_descriptor.__new__() 
>>> 

私はそれのpythonを通じてそれを行うことは不可能ですかなり確信しているが、どのように私はctypesのか、のようなものを通してそれを行うことができますcffi?さて

+0

私はあなたの質問を理解しているとは確信していませんが、おそらく[プロパティ](https://docs.python.org/3/howto/descriptor.html?highlight=property#properties)に興味がありますか?そうでない場合は、動作していないコードを表示して、あなたが取得しようとしているものを明確にすることができますか? –

+0

残念ながら、コードは単純に表示するには大きすぎますが、上のコンソールの例では一般的な考え方を示しています。関数に含まれているかsetattr()などによって関係なく同じ動作をしています。 .. 私がしようとしているのは、クラスからディスクリプタを分離することです。ディスクリプタへのインスタンスアクセスを必要とせず、したがって民営化も必要ありません。 – Tcll

+0

私は現在、最初の2人でsetattr()を基本的にやっているので、3番目のクラスが壊れる原因となるものがあるかどうかを調べようとしています。 https://stackoverflow.com/questions/20019333/modify-class-dict-mappingproxy-in-python – Tcll

答えて

0

__slots__クラスは基本的にmember_descriptorインスタンスは、基本的に構造体のインスタンスへのポインタを処理するラッパーであるC struct{}、あるので、定義されたクラスの外側member_descriptorを作成することは、正確に可能ではない...

def private(): 
    privateRegistry = {} # as long as I don't need access to private attributes within __hash__ it won't infinitely recurse 
    getprivate = privateRegistry.__getitem__; setprivate = privateRegistry.__setitem__ # just for quick access 

    class privateAttrs(object): 
     __slots__ = ['a'] 
    get_a, set_a = getset(privateAttrs, 'a', privatize=False) # just for quick access 

    new = object.__new__ 
    class Object(object): 
     __slots__ = ['public'] 
     def __new__(cls): 
      i = new(cls) 
      p = new(privateAttrs); setprivate(i, p) 
      set_a(p, 15) # p.a = 15 with no dot operator slowness since you're calling __set__ directly 

     def __getitem__(i, item): 
      p = getprivate(i) 
      return get_a(p) 

    return Object 

Object = private() 
del private 

何か:と私は理解して、既存の構造体の定義を変更することはできません...

ので、私は最終的にはそうのようなプライベートな属性を格納するための回避策として代替民営化クラスを使用した上で決めました私また、私は、これは本当にプライベートではありません知っているが...

EDITは、私が上記UGECollectionと同様に民営化しています約15クラスのうち、面白いけれども... 、UGECollectionが唯一の犯罪者です見つけます__not_so_private属性よりも優れています...
オブジェクトのメソッドのいずれかを選択して、プライベート属性(この場合はプライベートクラス自体)の特定のゲッターとセッターにアクセスするには、__closure__から書き込み可能です読み込み専用のプロパティ)がありますが、セルがキー設定されているのではなくインデックスされているため、セルがアクティブなプロジェクトと同じ順序(まったく)であるとは期待できないため、

関連する問題