Python属性、方法和类管理系列之----属性初探

时间:2022-12-21 18:49:27

在学习dict的时候,肯定听过dict是Python中最重要的数据类型,但是不一定知道为什么。马上你就会明白原因了。

Python中从模块、到函数、到类、到元类,其实主要管理方法就是靠一个一个的字典。

函数dir

先来学一个重要的内置函数。

dir返回一个列表。

列表中包含了实例的属性名,实例的类的属性名,实例的所有超类的属性名。

如果你想获取一个对象所有有效属性,你应该使用dir()来替代__dict__或者__slots__

我们先来写一个没有什么实际意义的module。

a.py

print('start')
import sys
from threading import Thread
import datetime
def f1():
x=a #这里故意设置了一个没有初始化的变量a
def inner():
y=1
return y
return inner class A:
xx=1
def f2(self):
yy=2
return yy a=A()
print('end')

模块的重要属性

在Python运行的时候,会从上到下把变量放入一个叫__dict__字典中,并运行所有的打印语句。

>>> import a
start #打印语句会全部运行。
end
>>> a.__dict__.keys() #会把全局变量放在这个字典中,同时Python会自动生成一些字典键值对。
dict_keys(['__name__', '__package__', '__doc__', '__loader__', 'datetime', 'A', '__spec__', '__builtins__', '__cached__', '__file__', 'f1', 'sys', 'a', 'Thread'])

你肯定听说过import和from语句是隐形的赋值语句,现在可以看到他们的名字出现在这个字典中了吧。

你也肯定听说过def和class语句是隐形的赋值语句,找找看是不是也出现在这个字典中了?

当然还包括我们的赋值语句中定义的变量a了。

现在我们进一步探究一下这个有用的字典。


>>> a.__builtins__.keys() #这个是builtins模块中定义的所有变量,中间省略了很多。
#Python判断我们的一个变量是否定义过,就是看变量是否出现在a.__dict__或a.__builtins__中。
dict_keys(['setattr', 'slice', 'ZeroDivisionError', 'IndexError', 'KeyError', 'TimeoutError', 'map', 'isinstance', 'bin', 'bytearray', 'zip', 'locals', 'IsADirectoryError', 'AttributeError', ...'False', 'print', 'vars', 'exit', 'EnvironmentError'])
>>> a.__doc__ #这个是模块的文档字符串,由于我们没有定义,所以为Null
>>> a.__file__ #这个是运行的文件名。
'/home/aaa/proj/a.py'
>>> a.__name__ #这个是我们的文件名,不包括路径和扩展名py
'a'

额外说一句,如果我们直接运行一个Python文件,那么这个文件会出现在sys.modules中,事实上,我们所有import的对象都会出现在这个字典中。

>>> sys.modules[__name__]
<module '__main__' (built-in)> #这个就是我们运行的Python文件。
>>> sys.modules['datetime']
<module 'datetime' from '/usr/lib/python3.4/datetime.py'> #这是我们导入的datetime文件。
>>> sys.modules['logging'] #我们没有import过logging模块,所以找不到。
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'logging'

函数的重要属性

我们在a.py中输入一下测试内容。

g=55
def f1(arg=2,arg2='c',*,kargs=3,kargs2='dd'):
x=a #这里故意设置了一个没有初始化的变量a
def inner():
y=1
return y
return inner
f1.val=3
f1.val2='python'

我们运行下面的测试内容来进行探索。

>>> from a import f1
>>> f1.__class__ #由于Python内部采用function类来创建函数,所以函数是function类的实例,通过__class__可以看到一个实例的类。
<class 'function'>
>>> f1.__module__ #找到函数属于那个模块
'a'
>>> f1.__name__ #函数的名词
'f1'
>>>f1.__code__ #这是f1的代码对象,请移步"解释型和编译型语言的区别以及Python的运作方式"去查看。
>>> f1.__globals__.keys() #该函数能够使用的所有全局变量,所以Python通过如果判断函数中的变量没有在本地定义,且不在f1.__dict__中,且不在f1.__globals__字典中,且不在f1.__modules__.__builtins__中的话,那么会报参数为定义的错误。
dict_keys(['f1', '__name__', '__doc__', '__builtins__', '__file__', '__spec__', '__cached__', '__package__', 'g', '__loader__'])
>> f1.__dict__ #如果定义了函数的属性,那么出现在__dict__中。
{'val2': 'python', 'val': 3}
>>> f1.__defaults__ #如果定义了位置默认参数,那么出现在这个字典中,也就是说函数的默认参数是在函数定义的时候评估的
(2, 'c')
#如果默认参数获取失败,那么函数定义就会失败。
>>> def f(x=c):... #默认参数评估出错,定义阶段就会报错。
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'c' is not defined
>>> def ff(x): #如果是函数内部变量评估出错,那么函数定义阶段捕获报错,但是运行阶段会报错。
... x=c
...
>>> ff(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
NameError: name 'c' is not defined
>>> f1.__kwdefaults__ #关键字参数的默认参数放在__kedefaults__中。
{'kargs': 3, 'kargs2': 'dd'}

我知道如果我们定义类,那么Python默认采用元类type来初始化该类,而且我会在元类部分详细介绍其运作方式。

我知道我们的函数是通过class function来初始化的,但是具体的运作方式有所不知,如果你知道哪里有介绍内容,麻烦通过评论或者邮箱jessonsh@163.com发给链接给我。

类和实例的重要属性

这个很重要,我们先稍微了解一下,在下面几篇文章中,我会着重介绍。

先定义一个简单的类:

a.py

g=55
class Desc:
def __get__(self,ins, cls):
print(self)
class A:
arg=2
arg2=Desc()
def __init__(self, name, age):
self.name = name
self.age=age
def f2(self,x=1):
y='a'
print(x)

下面开始我们的测试:

>>> from a import A
>>> dir(A) #所有A可以用的属性名列表
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'arg', 'arg2', 'f2']
>>> A.__doc__ #A的文档字符串
>>> A.f2 #A中定义的方法f2,每个定义的方法名都会出现在A.__dict__中。
<function A.f2 at 0x7f970a8d2bf8>
>>> A.__module__ #A所在的模块名。
'a'
>>> A.arg #A中的所有属性都会出现在A.__dict__中。
2
>>> A.arg2 #这是A的arg2属性,是一个描述符对象。
<a.Desc object at 0x7f11f25e7588>
>>> A.__dict__ #类A的__dict__属性,这是一个相当重要的属性。
mappingproxy({'arg': 2, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None, 'arg2': <a.Desc object at 0x7f9708995550>, '__module__': 'a', '__dict__': <attribute '__dict__' of 'A' objects>, 'f2': <function A.f2 at 0x7f970a8d2bf8>})
>>> ins=A('js',22)
>>> ins.__dict__ #这是A的实例ins的__dict__对象,在很多时候,该属性需要看类A的__dict__的脸色。
{'age': 22, 'name': 'js'}

总结

  1. 模块、类、函数均有以下属性:

    __dict__:该对象的属性字典。

    __doc__:返回说明性的文字,定义在块语句的最前面

    __name__:返回该对象的名字

  2. 类、函数均有以下属性:

    __module,用来返回该对象的模块名。

    __class__:用来返回类的类型(或者实例的类)、或者函数的类型

    __globals__:用来返回该对象所有可用的全局变量名。

  3. 模块有__file__属性,用来返回模块包含路径的文件名,有__builtins__属性,用来返回所有的可以使用的内置函数、内置异常对象、内置保留字等对象。

    无论在任何位置,Python均会按照LEGB法则,在最后搜索模块的__builtins__属性,来最后判断该变量是否已经定义。

  4. 模块、类、寒酸通过调用dir函数,可以得到该对象实际可以使用的所有属性。

Python属性、方法和类管理系列之----属性初探的更多相关文章

  1. Python属性、方法和类管理系列之----描述符类

    什么是描述符类? 根据鸭子模型理论,只要具有__get__方法的类就是描述符类. 如果一个类中具有__get__和__set__两个方法,那么就是数据描述符,. 如果一个类中只有__get__方法,那 ...

  2. Python属性、方法和类管理系列之----&lowbar;&lowbar;slots&lowbar;&lowbar;属性

    一句话说明 __slots__是用来限制实例的属性的,__slots__可以规定实例是否应该有__dict__属性:__slots__不能限制类的属性. 只有__slots__列表内的这些变量名可赋值 ...

  3. Python属性、方法和类管理系列之----元类

    元类的介绍 请看位于下面网址的一篇文章,写的相当好. http://blog.jobbole.com/21351/ 实例补充 class Meta(type): def __new__(meta, c ...

  4. python 面向对象静态方法、类方法、属性方法、类的特殊成员方法

    静态方法:只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性. 在类中方法定义前添加@staticmethod,该方法就与类中的其他(属性,方法)没有关系,不能通过实例化类调用方法使用 ...

  5. Python面向对象4:类的相关函数与属性

    1 类相关函数- issubclass:检测一个类是否是另一个类的子类- isinstance:检测一个对象是否是一个类的实例- hasattr:检测一个对象是否由成员xxx- getattr: ge ...

  6. 对象属性拷贝工具类大全&equals;&equals;&gt&semi;Bean的属性拷贝从此不用愁

    大家在做java开发时,肯定会遇到api层参数对象传递给服务层,或者把service层的对象传递给dao层,他们之间又不是同一个类型对象,但字段又是一样,如果还是用普通的get.set方式来处理话,比 ...

  7. Python - 关于属性访问的优先级,属性访问顺序,python attributel lookup,类和实例访问属性的顺序

    object.__getattribute__(self, name) 类中的数据描述符 object.__dict__.get(name) 自身属性字典 object.__class__.__dic ...

  8. python特殊方法定制类

    #coding:utf-8class RoundFloat(object): def __init__(self,val): assert isinstance(val, float),"v ...

  9. Python中的私有属性私有方法、类属性类方法以及单例设计模式

    私有属性是对象不希望公开的属性,私有方法是对象不希望公开的方法.在定义私有属性和私有方法时,在属性或者方法前,加上__(两个下划线) 公有方法可以通过对象名直接调用,私有方法不能通过对象名直接调用,只 ...

随机推荐

  1. laravel框架总结&lpar;十二&rpar; -- 关联关系

    这里我们users表对应的模型类名是users,大家特意注意下和user取名的不同 1.一对一关系 1>表A和表B的记录一一对应,比如一个用户对应一个社交账号 数据表的设计如下:   2> ...

  2. 初识JavaScript,Ajax,jQuery,并比较三者关系

    一.基本认识 1.JavaScript 定义: javaScript的简写形式就是JS,是由Netscape公司开发的一种脚本语言,一种广泛用于客户端Web开发的脚本语言,常用来给HTML网页添加动态 ...

  3. 优秀团队建设--美国式团队&lpar;ppt&rpar;

    美国式团队 一.团队精神 团队精神反映一个人的素养.一个人的能力,一个人与别人合作的精神和能力.一个团队是个有机的总体,作为个人,仅仅有全然融入到这个有机总体之中,才干最大限度地体现自己的价值. 团队 ...

  4. Web 前台优化

    大型网站--前端性能优化和规范 2013-10-28 09:00 by 贤达, 2769 阅读, 10 评论, 收藏, 编辑   Web性能涉及的范围太广,但一般web开发者在程序上线以后很多都曾遇到 ...

  5. VS code 中的各种变量 &dollar;&lbrace;file&rcub;&comma;&dollar;&lbrace;fileBasename&rcub;

    VS code 中的各种变量 ${file},${fileBasename} 2017年08月24日 11:14:07 bailsong 阅读数:7108    from: https://blog. ...

  6. Python之给程序传参数

    1.代码 import sys # 导入系统 args = sys.argv # 获取系统参数 if(args.__len__() == 2): print("%s是世界上最好的语言!&qu ...

  7. 【bzoj3039】玉蟾宫 悬线法

    悬线法是一种更优秀的枚举方式,保证了枚举悬线的集合包含了极大子矩形所在的集合,而且由最大子矩形一定是极大子矩形的定理可知,这种枚举方式可以求出最大子矩形. 具体做法是维护矩形中每个元素对应最近的左边和 ...

  8. poj3074 DLX精确覆盖

    题意:解数独 分析: 完整的数独有四个充要条件: 1.每个格子都有填数字 2.每列都有1~9中的每个数字 3.每行都有1~9中的每个数字 4.每个9宫格都有1~9中的每个数字 可以转化成精确覆盖问题. ...

  9. 闭合浮动的方法css

    浮动是一个有意思(你也可以说它很麻烦)的CSS属性,任何元素设置了浮动,层级就提高了,会影响它后面没设置浮动的元素,这些倒霉的被影响者会跑到浮动层的下面去(当然IE6.IE7除外),那解决方法呢? 常 ...

  10. mysql varchar 转 decimal

    在我们写代码的实际业务中,有时候实体类用的是String,数据库中自然是VARCHAR类型,但是如果这个实体的属性值放的是数字类型,你查询的时候又需要对它进行排序.sql怎么写呢. 别担心MySQL提 ...