小言_互联网的博客

Python常用内建属性详解

352人阅读  评论(0)

常用内建属性

class

用于查看当前对象所属的类

>>> age = 35
>>> age.__class__
<type 'int'>
>>> name = 'bob'
>>> name.__class__
<type 'str'>
>>> def foo(): pass
>>>foo.__class__
<type 'function'>
>>> class Bar(object): pass
>>> b = Bar()
>>> b.__class__
<class '__main__.Bar'>

slots

  • 动态语言:可以在运行的过程中,修改代码
  • 静态语言:编译时已经确定好代码,运行过程中不能修改

如果我们想要限制实例的属性怎么办?比如,只允许对Person实例添加name和age属性。

为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:

>>> class Person(object):
    __slots__ = ("name", "age")

>>> P = Person()
>>> P.name = "老王"
>>> P.age = 20
>>> P.score = 100
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
AttributeError: Person instance has no attribute 'score'
>>>

注意:

  • 使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的
In [67]: class Test(Person):
    ...:     pass
    ...:

In [68]: t = Test()

In [69]: t.score = 100 

doc

表示类的描述信息

class Foo:
    """ 描述类信息,这是用于看片的神奇 """
    def func(self):
        pass

print(Foo.__doc__)
#输出:类的描述信息

module

module 表示当前操作的对象在那个模块

test.py

class Person(object):
    def __init__(self):
        self.name = 'laowang'

main.py

from test import Person

obj = Person()
print(obj.__module__)  # 输出 test 即:输出模块
print(obj.__class__)  # 输出 test.Person 即:输出类

dict

类或对象中的所有属性
类的实例属性属于对象;类中的类属性和方法等属于类,即:

class Province(object):
    country = 'China'

    def __init__(self, name, count):
        self.name = name
        self.count = count

    def func(self, *args, **kwargs):
        print('func')

# 获取类的属性,即:类属性、方法、
print(Province.__dict__)
# 输出:
# {'__dict__': <attribute '__dict__' of 'Province' objects>, 
# '__module__': '__main__', 
# 'country': 'China', 
# '__doc__': None, 
# '__weakref__': <attribute '__weakref__' of 'Province' objects>, 
# 'func': <function Province.func at 0x101897950>, 
# '__init__': <function Province.__init__ at 0x1018978c8>}


# 获取对象的属性 
obj1 = Province('山东', 10000)
print(obj1.__dict__)
# 获取 对象obj1 的属性
# 输出:{'count': 10000, 'name': '山东'}

obj2 = Province('山西', 20000)
print(obj2.__dict__)
# 获取 对象obj1 的属性
# 输出:{'count': 20000, 'name': '山西'}

内建属性集合

getattribute 用法和坑

例子

class Itcast(object):
    def __init__(self,subject1):
        self.subject1 = subject1
        self.subject2 = 'cpp'

    #属性访问时拦截器,打log
    def __getattribute__(self,obj):
        if obj == 'subject1':
            print('log subject1')
            return 'redirect python'
        else:   #测试时注释掉这2行,将找不到subject2
            return object.__getattribute__(self,obj)

    def show(self):
        print('this is Itcast')

s = Itcast("python")
print(s.subject1)
print(s.subject2)

运行结果

log subject1
redirect python
cpp

有可能写出来的坑

class Person(object):
        def __getattribute__(self,obj):
            print("---test---")
            if obj.startswith("a"):
                return "hahha"
            else:
                return self.test


        def test(self):
            print("heihei")


t.Person()

t.a #返回hahha

t.b #会让程序死掉
"""
原因是:当t.b执行时,会调用Person类中定义的__getattribute__方法,
    但是在这个方法的执行过程中if条件不满足,所以, 程序执行else里面的代码,即return self.test  
问题就在这,因为return 需要把self.test的值返回,那么首先要获取self.test的值,因为self此时就是t这个对象,
    所以self.test就是t.test 此时要获取t这个对象的test属性,那么就会跳转到__getattribute__方法去执行,
    即此时产生了递归调用,由于这个递归过程中 没有判断什么时候推出,所以这个程序会永无休止的运行下去,
    又因为每次调用函数,就需要保存一些数据,那么随着调用的次数越来越多,最终内存吃光,所以程序 崩溃
注意:以后不要在__getattribute__方法中调用self.xxxx
"""

mro

类名.__mro__
可以查看C类的对象搜索方法时的先后顺序 ,通过C3算法给出先后的继承顺序


转载:https://blog.csdn.net/YiJie__ShuSheng/article/details/105385566
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场