02-25
今天生日,学习笔记也从今天开始记录
直到今天为止,一共学习了12天,首先,先来复习一下Day01的课程
Day 01
第一天主要的作用是了解Python,安装Python和Pycharm编译器
Python的作用在这就不多做解释,网上很多方面的应用
- 安装Python
去百度直接搜索Python,选择Python3下载 或者 点击Python进入官网下载
双击下载包即可安装 - 安装Pycharm
同理,去百度搜索,或者去Pycharm官网下载
速度可能有点慢,别着急
双击下载包即可安装
接下来是今天的学习笔记 Day12
仅个人理解,有问题请指出!
Day12
1.self的使用
self在定义__init__
的时候会自动声明,用来传递关键类传入的参数,例如
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print(self.name + '正在吃东西')
p1 = Person('张三', 18)
p2 = Person('李四', 20)
p1.eat()
在p1
调用eat()
方法的时候,self获取的是p1
当中的name
如果p2
调用eat()
方法的话,self获取的是p2
当中的name
2.运算符相关的魔法方法
- 魔法方法
__eq__
当使用==
比较两个值/数时,会自动调用__eq__
方法,可以在class类里重新编写
例如
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
print(p1 == p2) # False
修改前print(p1 == p2)
的结果为False
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
return self.name == other.name and self.age == other.age
print(p1 == p2) # True == 运算符本质是调用对象的 __eq__ 方法的返回结果 重写以后可以变为True
修改后print(p1 == p2)
的结果为True
- 魔法方法
__add__,__sub__,__mul__,__truediv__
对应加减乘除
当使用+ - * /
的时候自动调用
def __add__(self, other):
return self.age + other.age
在return self.age + other.age
中+
可以替换成- * /
来对应相应的魔法方法
- 魔法方法
__int__,__float__
在使用int()或者float()时会自动使用,在这就不做演示
3.内置属性
-
__slots__ = ('name','age')
表示能出现的属性有name和age
class Person(object):
'''
这是一个人类
'''
def __init__(self, name, age):
self.name = name
self.age = age
__slots__ = ('name', 'age') # 能出现的属性
-
__dict__
把对象属性和值转换成为一个字典 -
__dir__
等价于dir()
用来查看所有属性和方法 -
__doc__
查看类中的说明,使用方法可以有一下两种
print(p.__doc__) # 对象名.__doc__
print(Person.__doc__) # 类名.__doc__
4.把对象当做字典使用
class Person(object):
'''
这是一个人类
'''
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print(self.name + '正直吃饭')
def __setitem__(self, key, value):
self.name = value
def __getitem__(self, item):
return self.__dict__[item]
p = Person('张三', 18)
print(p.__dict__) # {'name': '张三', 'age': 18} 把对象属性和值转换成为一个字典
# 不能直接把一个对象当做字典使用
p['name'] = 'jack' # 在未编写__setitem__方法时会报错
print(p.name)
print(p['name']) # 会调用__getitem__方法(同样要编写以后才能调用)
5.对象属性和类属性
class Person(object):
type = '人类'
'''
这是一个人类
'''
def __init__(self, name, age):
self.name = name
self.age = age
↑
此时先定义了一个类属性
# 对象 P1 和 p2 都是通过 Person 类创建出来的实例对象
# name 和 age 是对象属性,在__init__方法里以参数的形式定义的
# 是每一个实例对象都会单独保存一份的属性
# 没一个实例对象之间的属性没有关联,互不影响
p1 = Person('张三', 18)
p2 = Person('李四', 19)
# 类属性可以通过类对象和实例对象获取
print(Person.type) # 人类 可以通过类对象寻找类属性
# 也可以通过实例对象寻找类属性
print(p1.type) # 人类
print(p2.type) # 人类
↓
此时更改p1.type = 'human'
这时是新增了一个对象属性,不是覆盖
p1.type = 'human'
print(Person.type) # 人类
print(p1.type) # human 新增了一个对象属性
print(p2.type) # 人类
↓
当我们修改Person.type = 'monkey'
# 类属性只能通过类对象来修改,实例对象无法修改类属性
Person.type = 'monkey'
print(Person.type) # monkey
print(p1.type) # human
print(p2.type) # monkey
6.私有属性
在定义类的时候,使用双下划线来定义私有属性/方法
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
self.__money = 1000 # 以两个下划线定义的变量是私有变量
def __demo(self):
print('我是demo函数,name={}'.format(self.name))
如何获取私有属性呢?
1.使用对象._类名__私有变量名
获取
print(p._Person__money) # 通过这种方式也能获取到私有属性
2.定义get和set方法进行获取
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
self.__money = 1000
def get_money(self):
# 记录
print('{}查询余额.'.format(datetime.datetime.now()))
return self.__money
def set_money(self, qian):
if type(qian) != int:
print('设置的余额不合法')
return
print('修改余额了')
self.__money = qian
def __demo(self):
print('我是demo函数,name={}'.format(self.name))
def test(self):
self.__demo()
p = Person('张三', 18)
p.test() # 我是demo函数,name=张三
print(p.get_money())
# 2020-02-25 21:47:05.297043查询余额.
# 1000
p.set_money(100)
# 修改余额了
print(p.get_money())
#2020-02-25 21:47:05.297043查询余额.
#100
7.类方法和静态方法
class Person(object):
type = '人类'
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, food): # 对象方法有一个参数self,指的是实例对象
print(self.name + '正在吃' + food)
# 如果一个方法里没有用到任何的实例对象的任何属性,可以将这个方法定义成static(静态方法)
@staticmethod
def demo(): # 默认分方法都是对象方法
print('hello')
@classmethod
def test(cls): # 如果这个函数只用到了类属性,我们可以把他定义成为一个类方法
# 类方法会有一个参数cls,也不需要手动传参,会自动传参
# cls 指的是类对象 cls == Person # True
print(cls.type)
print('yes')
class Calculator():
@staticmethod
# 如果一个方法里没有用到任何的实例对象的任何属性,可以将这个方法定义成static(静态方法)
def add(a, b):
return a + b
@staticmethod
def minus(a, b):
return a - b
@staticmethod
def mul(a, b):
return a * b
c = Calculator()
print(c.add(1, 2))
print(Calculator.add(1, 2))
print(Calculator.minus(4, 3))
print(Calculator.mul(3, 4))
p1 = Person('张三', 18)
# 实例对象在调用方法时,不需要给形参self传参,会自动把实例对象传递给self
p1.eat('饺子')
p2 = Person('李四', 19)
# print(p1.eat)
# print(p2.eat)
print(p2.eat is p1.eat)
print(Person.eat)
# 对象方法还可以使用 类对象来调用类名.方法名()
# 这种方式,不会自动给self传参,需要手动的指定self
# Person.eat('西红柿鸡蛋盖饭') # eat() missing 1 required positional argument: 'food'
# staticmethod 没有用到类和实例对象内部中函数的参数,所以可以直接调用
Person.demo()
p1.demo()
# classmethod类方法
p1.test()
Person.test()
总结:静态方法可以通过类名.方法名
直接调用,而类方法只能通过创建一个对象以后通过对象名.方法名
使用,如果使用类名.方法名
使用则会报错.
8.单列设计模式
class Singleton(object):
instance = None # 类属性
__is_first = True
def __new__(cls, *args, **kwargs):
if cls.instance is None:
# 申请内存,创建一个对象,并把对象的类型设置为cls
cls.instance = object.__new__(cls)
return cls.instance
def __init__(self, a, b):
if self.__is_first:
self.a = a
self.b = b
self.__is_first = False
# 1.调用__new__方法申请内存
# 如果重写 __new__ 方法 , 会调用 object 的 __new__ 方法
# object的__new__方法会申请内存
# 如果重写了__new__方法,需要自己手动申请内存
s1 = Singleton('呵呵', '嘿嘿嘿')
s2 = Singleton('哈哈', '嘻嘻嘻')
s3 = Singleton('嘎嘎', '嘤嘤嘤')
print('0x%X' % id(Singleton))
print(s1 is s2) # True
print(s1.a, s2.a)
print(s1.b, s2.b)
print(s1.a, s1.b)
# print(type(s1))
↑
__new__
还不是很能理解,求教导!
网友评论