廖雪峰Python3学习笔记1

本文是笔者学习廖雪峰Python3教程的笔记,在此感谢廖老师的教程让我们这些初学者能够一步一步的进行下去.如果读者想学习完成的教程,请访问廖雪峰Python3教程,笔记如有侵权,请告知删除...

__slots__

  • 使用__slots__来限制实例能添加的属性
  • 使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的
  • 除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。
class Student(object): 
  __slots__ = ('name', 'age')

@property

  • 把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值
class Screen(object):

   @property
   def width(self):
       return self._width

   @width.setter
   def width(self, value):
       self._width = value

   @property
   def height(self):
       return self._height

   @height.setter
   def height(self, value):
       self._height = value

   @property
   def resoluation(self):
       return self._width*self._height

MixIn

MixIn是一种多继承, 只需要在定义类型后面的小括号里用逗号分割添加新的继承类即可

class MyTCPServer(TCPServer, ForkingMixIn):
   pass
   ```

#定制类

类似\_\_slots\_\_这种形如\_\_xxx\_\_的变量或者函数名就要注意,这些在Python中是有特殊用途的。例如\_\_len\_\_()方法是为了能让class作用于len()函数。

- ## \_\_str__

def str(self):
return 'Student object (name: %s)' % self.name

在类中写这段 使用print进行打印输出的时候就会按照格式显示,但是如果不用print打印则不会按照格式输出

 这是因为直接显示变量调用的不是\_\_str\_\_而是\_\_repr\_\_()来返回用户看到的字符串,而\_\_repr\_\_()返回的是程序开发者所看到的字符串,也就是说\_\_repr\_\_()是为调试服务的.
 
 解决办法是在写一个\_\_repr\_\_()方法,但是由于\_\_str\_\_和\_\_repr\_\_()方法通常一样,所以简单的写法为
 
 ```class Student(object):
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return 'Student object (name=%s)' % self.name
    __repr__ = __str__
    ```
    
- ## \_\_iter\_\_
    
    如果一个类想被用于for...in循环,类似list和tuple.那就必须实现一个\_\_iter\_\_()方法,该方法的返回值是一个可迭代的对象,然后Python的for循环就会不断调用\_\_next\_\_()方法拿到循环的下一个值,知道遇到stopIteration抛出异常为止
    
    ```
    #斐波那契数列
    class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1 # 初始化两个计数器a,b

    def __iter__(self):
        return self # 实例本身就是迭代对象,故返回自己

    def __next__(self):
        self.a, self.b = self.b, self.a + self.b # 计算下一个值
        if self.a > 100000: # 退出循环的条件
            raise StopIteration();
        return self.a # 返回下一个值
  • __getitem__

实现了__iter__方法之后,虽然能够使用for循环进行迭代,但是并不能像list似的使用下标来访问其中的元素,若要实现该功能则需要实现__getitem__()方法

class Fib(object):
   def __getitem__(self, n):
       a, b = 1, 1
       for x in range(n):
           a, b = b, a + b
       return a

这样做虽然可以使用下标进行访问了,但是对于list(range(10))[2:9]这样的切片方法却行不通,原因是getitem()传入的参数可能是一个int,也可能是一个切片对象slice,这个时候就需要就传入的参数进行判断了

  • __getattr__

使用Python的另一个机制是写一个getattr()方法,动态返回一个属性。可以避免因为调用不存在的属性出现的错误.这个方法只有在没有找到属性的情况下才会调用, 这个方法同样可以返回一个函数.

class Student(object):

   def __init__(self):
       self.name = 'Michael'

   def __getattr__(self, attr):
       if attr=='score':
           return 99
# 返回一个函数
class Student(object):

   def __getattr__(self, attr):
       if attr=='age':
           return lambda: 25

这样在调用Student类的score这个不存在的属性的时候就不会出现错误信息而是返回99这个数

  • __call__

一个对象实例可以有自己的属性和方法,当我们调用实例方法时使用__call__可以直接在实例本身上调用方法.

任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用.

class Student(object): 
  def __init__(self, name): 
    self.name = name
 def __call__(self): 
    print('My name is %s.' % self.name)

# 调用方法:
s = Student('Joe')
s() # self参数不要传入
My name is Joe.

枚举类

  • Python中的枚举类型需要先从enum模块中引入Enum类.
    然后创建一个枚举
from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

如上所示即获得了Month类型的枚举,可以使用Month.Jan, Month.Feb 这种类型进行访问, 也可以使用forin来遍历

for name, member in Month.__members__.items():
   print(name, '=>', member, ',', member.value)

member.value是自动给枚举赋值的,赋值从1开始

  • 如果要精确的控制枚举类型, 可以从Enum派生出自定义类.
from enum import Enum, unique
@unique
class Weekday(Enum):
   Sun = 0 # Sun的value被设定为0
   Mon = 1
   Tue = 2
   Wed = 3
   Thu = 4
   Fri = 5
   Sat = 6

其中装饰器@unique的作用是检查name所对应的value值是否唯一

  • 访问方式有很多

    例如:
    Weekday['Tue']
    Weekday(1)
    Weekday.Sun
    Weekday.Tue.value
    ......

元类

  • type()

    Python是一门动态语言,他所有的类和方法都不是在编译的时候创建的,而是在运行的时候创建的.

    type()既可以返回一个class类型,也使用type()可以在运行时动态的创建一个class.无需经过class name(object):来定义

    • 首先定义一个方法
    def fn(self, name = 'world'):
        print('Hello %s' % name)
    
    • 使用type()方法创建一个class

    Hello = type('Hello', (object, ), dict(hello = fn))

    • type()的三个参数

    1.第一个参数是定义的class的名字
    2.第二个参数是继承的类,这是一个tuple.如果不是多继承的话,需要传入一个单元素的元组(object,)
    3.第三个参数是方法名与函数的绑定,将在类外面定义的函数绑定到类的方法上

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

推荐阅读更多精彩内容