python 对象属性

python一切皆对象。

#!/usr/bin/env python
#-*- coding = utf-8 -*-

'''
    @Author: hszhang@foxmail.com
    @Date  : 2019/4/26
    @Desc  : Invest entry(main)
'''

# 新式类
class ClassA(object):

    num_A = 1

    def foo_A(self):
        pass

    def __str__(self):
        return 'this is ClassA'


class ClassB(ClassA):

    num_B = 2

    def __init__(self, name='ClassB'):
        self.name = name

    def foo_B(self):
        pass
  • 查看类的属性
print(dir(ClassA))
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'foo_A', 'num_A']
  • 基类的属性
print(ClassA.__dict__)

输出

{
	'__module__': '__main__', 
	'num_A': 1, 
	'foo_A': <function ClassA.foo_A at 0x00000000022A4620>,
	'__str__': <function ClassA.__str__ at 0x00000000022A46A8>,
	'__dict__': <attribute '__dict__' of 'ClassA' objects>,
	'__weakref__': <attribute '__weakref__' of 'ClassA' objects>,
	'__doc__': None
}
print(ClassB.__dict__)  # 类对象的__dict__不包含基类的属性
{
	'__module__': '__main__',
	'num_B': 2, 
	'__init__': <function ClassB.__init__ at 0x00000000028C4730>, 
	'foo_B': <function ClassB.foo_B at 0x00000000028C47B8>, 
	'__doc__': None
}
  • object.setattr(self, name, value)

实例对象通过instanceA.__setattr__赋值,被赋值的属性和值会存入实例属性字典__dict__中。

class ClassA(object):

    def __init__(self, classname):
        self.classname = classname

insA = ClassA('ClassA')

print(insA.__dict__)
# {'classname': 'ClassA'}

insA.tag = 'insA'    

print(insA.__dict__)
# {'tag': 'insA', 'classname': 'ClassA'}
  • object.getattr(self, name)

实例instance通过instance.getattr_访问属性name,只有当属性name没有在实例的__dict__或它构造类的__dict__或基类的__dict__中没有找到,才会调用__getattr_。

如果在__getattr__(self, attr)存在通过self.attr访问属性,会出现无限递归错误。

class ClassA(object):

    def __init__(self, classname):
        self.classname = classname

    def __getattr__(self, attr):
        return('invoke __getattr__', attr)

insA = ClassA('ClassA')
print(insA.__dict__) 
# {'classname': 'ClassA'}

print(insA.classname)    # 实例insA已经有classname属性了,不会调用__getattr__
# ClassA

print(insA.grade)         # grade属性没有找到,调用__getattr__
# ('invoke __getattr__', 'grade')
  • object.getattribute(self, name)

实例instance通过instance.__getattribute__访问属性name,__getattribute__方法一直会被调用,无论属性name是否追溯到。

如果在__getattribute__(self, attr)方法下存在通过self.attr访问属性,会出现无限递归错误。

  • 剖析一下addic的源码
import copy


class Dict(dict):

    def __init__(__self, *args, **kwargs):
        object.__setattr__(__self, '__parent', kwargs.pop('__parent', None))
        object.__setattr__(__self, '__key', kwargs.pop('__key', None))
        for arg in args:
            if not arg:
                continue
            elif isinstance(arg, dict):
                for key, val in arg.items():
                    __self[key] = __self._hook(val)
            elif isinstance(arg, tuple) and (not isinstance(arg[0], tuple)):
                __self[arg[0]] = __self._hook(arg[1])
            else:
                for key, val in iter(arg):
                    __self[key] = __self._hook(val)

        for key, val in kwargs.items():
            __self[key] = __self._hook(val)

    def __setattr__(self, name, value):
        if hasattr(self.__class__, name):
            raise AttributeError("'Dict' object attribute "
                                 "'{0}' is read-only".format(name))
        else:
            self[name] = value

    def __setitem__(self, name, value):
        super(Dict, self).__setitem__(name, value)
        try:
            p = object.__getattribute__(self, '__parent')
            key = object.__getattribute__(self, '__key')
        except AttributeError:
            p = None
            key = None
        if p is not None:
            p[key] = self
            object.__delattr__(self, '__parent')
            object.__delattr__(self, '__key')

    def __add__(self, other):
        if not self.keys():
            return other
        else:
            self_type = type(self).__name__
            other_type = type(other).__name__
            msg = "unsupported operand type(s) for +: '{}' and '{}'"
            raise TypeError(msg.format(self_type, other_type))

    @classmethod
    def _hook(cls, item):
        if isinstance(item, dict):
            return cls(item)
        elif isinstance(item, (list, tuple)):
            return type(item)(cls._hook(elem) for elem in item)
        return item

    def __getattr__(self, item):
        return self.__getitem__(item)

    def __missing__(self, name):
        return self.__class__(__parent=self, __key=name)

    def __delattr__(self, name):
        del self[name]

    def to_dict(self):
        base = {}
        for key, value in self.items():
            if isinstance(value, type(self)):
                base[key] = value.to_dict()
            elif isinstance(value, (list, tuple)):
                base[key] = type(value)(
                    item.to_dict() if isinstance(item, type(self)) else
                    item for item in value)
            else:
                base[key] = value
        return base

    def copy(self):
        return copy.copy(self)

    def deepcopy(self):
        return copy.deepcopy(self)

    def __deepcopy__(self, memo):
        other = self.__class__()
        memo[id(self)] = other
        for key, value in self.items():
            other[copy.deepcopy(key, memo)] = copy.deepcopy(value, memo)
        return other

    def update(self, *args, **kwargs):
        other = {}
        if args:
            if len(args) > 1:
                raise TypeError()
            other.update(args[0])
        other.update(kwargs)
        for k, v in other.items():
            if ((k not in self) or
                (not isinstance(self[k], dict)) or
                (not isinstance(v, dict))):
                self[k] = v
            else:
                self[k].update(v)

    def __getnewargs__(self):
        return tuple(self.items())

    def __getstate__(self):
        return self

    def __setstate__(self, state):
        self.update(state)

    def setdefault(self, key, default=None):
        if key in self:
            return self[key]
        else:
            self[key] = default
            return default
  • hasattr(object, name)

判断object对象中是否存在name属性,当然对于python的对象而言,属性包含变量和方法;有则返回True,没有则返回False;需要注意的是name参数是string类型,所以不管是要判断变量还是方法,其名称都以字符串形式传参;getattr和setattr也同样;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值