02Python学习笔记之二.五【作用域、动态添加属性方法、types.MethodType、slots】2019-08-18

章节号 内容            
1图片格式(png) 宽度大于620px,保持高宽比减低为620px
1-1 应用
1-1-1 方法

第1章节  作用域

improt 库
#使用库内的对象
库.XXXXX
from 库 import *
#使用库内的对象,直接使用
XXXXX

  1、局部变量:在函数或方法内定义的变量globals()
  2、全局变量:在函数或方法外定义的变量locals()

In [1]: globals()
Out[1]: 
{'In': ['', 'globals()'],
 'Out': {},
 '_': '',
 '__': '',
 '___': '',
 '__builtin__': <module 'builtins' (built-in)>,
 '__builtins__': <module 'builtins' (built-in)>,
 '__doc__': 'Automatically created module for IPython interactive environment',
 '__loader__': None,
 '__name__': '__main__',
 '__package__': None,
 '__spec__': None,
 '_dh': ['/home/li'],
 '_i': '',
 '_i1': 'globals()',
 '_ih': ['', 'globals()'],
 '_ii': '',
 '_iii': '',
 '_oh': {},
 '_sh': <module 'IPython.core.shadowns' from '/usr/lib/python3/dist-packages/IPython/core/shadowns.py'>,
 'exit': <IPython.core.autocall.ExitAutocall at 0x7fbf75b9e438>,
 'get_ipython': <bound method InteractiveShell.get_ipython of <IPython.terminal.interactiveshell.TerminalInteractiveShell object at 0x7fbf75b35438>>,
 'quit': <IPython.core.autocall.ExitAutocall at 0x7fbf75b9e438>}

  ↑当前环境可用的所有全局变量。这个操作会显示之前使用过的一些变量,建议先退出一次再进入ipython查看。

In [2]: locals()
Out[2]: 
{'In': ['', 'globals()', 'locals()'],
 'Out': {1: {...}},
 '_': {...},
 '_1': {...},
 '__': '',
 '___': '',
 '__builtin__': <module 'builtins' (built-in)>,
 '__builtins__': <module 'builtins' (built-in)>,
 '__doc__': 'Automatically created module for IPython interactive environment',
 '__loader__': None,
 '__name__': '__main__',
 '__package__': None,
 '__spec__': None,
 '_dh': ['/home/li'],
 '_i': 'globals()',
 '_i1': 'globals()',
 '_i2': 'locals()',
 '_ih': ['', 'globals()', 'locals()'],
 '_ii': '',
 '_iii': '',
 '_oh': {1: {...}},
 '_sh': <module 'IPython.core.shadowns' from '/usr/lib/python3/dist-packages/IPython/core/shadowns.py'>,
 'exit': <IPython.core.autocall.ExitAutocall at 0x7fbf75b9e438>,
 'get_ipython': <bound method InteractiveShell.get_ipython of <IPython.terminal.interactiveshell.TerminalInteractiveShell object at 0x7fbf75b35438>>,
 'quit': <IPython.core.autocall.ExitAutocall at 0x7fbf75b9e438>}

  ↑当前环境可用的所有局部变量

In [3]: def fun():
   ...:     a=110
   ...:     print(locals())
   ...:     

In [4]: fun()
{'a': 110}

  ↑使用这个函数来显示fun()的所有局部变量。VScode中也能用。
  全局和局部,同名如何找:
  1、先找局部变量,即自己本域。
  2、再看是不是闭包,是闭包找外一域中有没有。
  3、再找全局环境看有没有。
  4、再找语言内建环境
  报错!

num=100
def test1():
    num=200
    def test2():
        num=300
        print(num)
    return test2

test1()()
300
num=100
def test1():
    num=200
    def test2():
        #num=300
        print(num)
    return test2

test1()()
200
num=100
def test1():
    #num=200
    def test2():
        #num=300
        print(num)
    return test2

test1()()
100

  LEGB规则:
  1、Locals
  2、Enclosing
  3、Globals
  4、Builtins

In [5]: dir(__builtin__)
Out[5]: 
['ArithmeticError',
 'AssertionError',
 'AttributeError',
 'BaseException',
 'BlockingIOError',
 'BrokenPipeError',
 'BufferError',
 'BytesWarning',
 'ChildProcessError',
 'ConnectionAbortedError',
 'ConnectionError',
 'ConnectionRefusedError',
 'ConnectionResetError',
 'DeprecationWarning',
 'EOFError',
 'Ellipsis',
 'EnvironmentError',
 'Exception',
 'False',
 'FileExistsError',
 'FileNotFoundError',
 'FloatingPointError',
 'FutureWarning',
 'GeneratorExit',
 'IOError',
 'ImportError',
 'ImportWarning',
 'IndentationError',
 'IndexError',
 'InterruptedError',
 'IsADirectoryError',
 'KeyError',
 'KeyboardInterrupt',
 'LookupError',
 'MemoryError',
 'ModuleNotFoundError',
 'NameError',
 'None',
 'NotADirectoryError',
 'NotImplemented',
 'NotImplementedError',
 'OSError',
 'OverflowError',
 'PendingDeprecationWarning',
 'PermissionError',
 'ProcessLookupError',
 'RecursionError',
 'ReferenceError',
 'ResourceWarning',
 'RuntimeError',
 'RuntimeWarning',
 'StopAsyncIteration',
 'StopIteration',
 'SyntaxError',
 'SyntaxWarning',
 'SystemError',
 'SystemExit',
 'TabError',
 'TimeoutError',
 'True',
 'TypeError',
 'UnboundLocalError',
 'UnicodeDecodeError',
 'UnicodeEncodeError',
 'UnicodeError',
 'UnicodeTranslateError',
 'UnicodeWarning',
 'UserWarning',
 'ValueError',
 'Warning',
 'ZeroDivisionError',
 '__IPYTHON__',
 '__build_class__',
 '__debug__',
 '__doc__',
 '__import__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 'abs',
 'all',
 'any',
 'ascii',
 'bin',
 'bool',
 'bytearray',
 'bytes',
 'callable',
 'chr',
 'classmethod',
 'compile',
 'complex',
 'copyright',
 'credits',
 'delattr',
 'dict',
 'dir',
 'display',
 'divmod',
 'dreload',
 'enumerate',
 'eval',
 'exec',
 'filter',
 'float',
 'format',
 'frozenset',
 'get_ipython',
 'getattr',
 'globals',
 'hasattr',
 'hash',
 'help',
 'hex',
 'id',
 'input',
 'int',
 'isinstance',
 'issubclass',
 'iter',
 'len',
 'license',
 'list',
 'locals',
 'map',
 'max',
 'memoryview',
 'min',
 'next',
 'object',
 'oct',
 'open',
 'ord',
 'pow',
 'print',
 'property',
 'range',
 'repr',
 'reversed',
 'round',
 'set',
 'setattr',
 'slice',
 'sorted',
 'staticmethod',
 'str',
 'sum',
 'super',
 'tuple',
 'type',
 'vars',
 'zip']

In [6]: 

第2章节  Python是动态语言

  静态语言是:运行之前要先编译的语言。
  动态语言可以:

In [7]: class cla(object):
   ...:     pass
   ...: 

In [8]: c=cla()

In [9]: dir(c)
Out[9]: 
['__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__']
In [10]: c.a=123

In [11]: dir(c)
Out[11]: 
['__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__',
 'a']

In [12]: 

  ↑定义的时候没有,运行的时候来添加一个a属性。

  • 2-1 Python是动态语言—添加属性

class cla(object):
    def __init__(self, name, age):
      self.name = name
      self.age = age

c=cla("zhangsan",40)
print(c.name)
print(c.age)

#动态给c添加一个addr,但是不影响其他的对象
c.addr="AAAAAAAAAAAAAAAAA"
print(c.addr)

#动态给cla类添加一个num,其他所有对象都可以使用
cla.num=0
print(c.num)

  ↑给类加,大家都可以用。
  ↑给对象加,自己用。

  • 2-2 Python是动态语言—添加方法

class cla(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def prii(self):
        print("pri")

def f1(self):
    print("f1")

c = cla("zhangsan", 40)

c.prii()

c.f1=f1
c.f1()

  1、在类外定义一个函数,填入一个形式参数。
  2、定义一个对象变量,把函数的引用传给这个变量
  3、使用变量()来调用函数
  注意:这样做,系统不会把对象当做参数传入给外部的这个函数,会报错。

  ↓解决问题使用到的模块和方法

In [12]: import types

In [13]: types.MethodType
Out[13]: method

In [14]: help(types.MethodType)

Help on class method in module builtins:

class method(object)
 |  method(function, instance)
 |  
 |  Create a bound instance method object.
 |  
 |  Methods defined here:
 |  
 |  __call__(self, /, *args, **kwargs)
 |      Call self as a function.
 |  
 |  __delattr__(self, name, /)
 |      Implement delattr(self, name).
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __get__(self, instance, owner, /)
 |      Return an attribute of instance, which is of type owner.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __hash__(self, /)
 |      Return hash(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  __reduce__(...)
 |      helper for pickle
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  __setattr__(self, name, value, /)
 |      Implement setattr(self, name, value).
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __func__
 |      the function (or other callable) implementing a method
 |  
 |  __self__
 |      the instance to which a method is bound

  ↓改为:

import types
class cla(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def prii(self):
        print("pri")

def f1(self):
    print("f1")

c = cla("zhangsan", 40)

c.prii()

c.f1=types.MethodType(f1,c)

c.f1()
pri
f1

第3章节  types.MethodType的作用

  • 3-1 types.MethodType的作用—添加实例方法

import types

class cla(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def prii(self):
        print("pri")

def f1(self):
    print("f1")

c = cla("zhangsan", 40)

c.prii()

c.f1=types.MethodType(f1,c)

c.f1()

xxx=types.MethodType(f1,c)

xxx()
pri
f1
f1

  ↑可以看到,xxx()一样可以正常的执行。所以这个动态添加的办法和原生的属性还是有所区别的。执行了types.MethodType(f1,c)之后,相当于产生了一个特殊返回值,这个返回值指向的f1的函数代码,里面已经被默认传递了c对象作为参数,只要使用这个返回值,就可以当做是调用了对象的方法。
  c.f1=types.MethodType(f1,c)这么写之后,再调用c.f1(),完全是为了字面上的符合,符合这个操作的原意而已。

  • 3-2 types.MethodType的作用—添加静态方法(未学)

  在使用静态方法时,类中的self将不会再进行传值,此时,静态方法已经和类没什么关系了。
  需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数。

import types

class cla(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def prii(self):
        print("pri")

def f1(self):
    print("f1")

#@符号,要想起装饰器!
@staticmethod
def test():
    print(":static")

c = cla("zhangsan", 40)

#这里不也不是必须叫cla.test,随便都可以
cla.test=test
cla.test()
:static

  ↑这里不需要绑定,因为静态方法不需要任何的参数,只要赋值了就直接用。注意要使用类名来调用。

  • 3-3 types.MethodType的作用—添加类方法

import types

class cla(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def prii(self):
        print("pri")

def f1(self):
    print("f1")

@staticmethod
def test():
    print(":static")

@classmethod
def clsm(cls):
    print("classmethod call")

c = cla("zhangsan", 40)

cla.clsm=clsm

cla.clsm()
classmethod call

  ↑类方法也是直接赋值调用就行。

  动态添加可以做到什么呢?一款APP,在没有进行整个APP的情况下,里面的部分功能变了。即我部分的功能代码存在一个文件中,我在后台默默更换这些文件,下次你再打开APP,对应的功能或者样式就变了。

第4章节  __slots__的作用

  注意点:
  1、锁死你属性的使用范围,slots了那些属性,就只能使用哪些属性,不能再随意添加。
  2、对派生的类不起作用。

class cla():
    def __init__(self, name, age):
        self.name = name
        self.age = age

   #锁死范围
    __slots__ = ("name", "age")


c = cla("lalala", "12")
c.addr = "123"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351