内置属性
可以使用内置函数
dir
查看一个对象支持的所有属性和方法,Python中存在很多的内置属性
class Person(object):
def __init__(self,name,age) -> None:
self.name = name
self.age = age
def run(self):
print(self.name + '正在吃饭')
p = Person('张三',18)
# 使用dir方法,查看该对象的所有内置属性
print(dir(p))
# ['__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__',
# 'age', 'name', 'run']
# 其中最后的'age','name','run'属性为自己定义的
# 其他为内置属性
# 内置属性示例:
print(p.__class__) # <class '__main__.Person'>
print(p.__dict__) # {'name': '张三', 'age': 18}
print(p.__dir__()) # 结果和dir(p)一样,dir(p)实际上就是调用了内置属性__dir__
print(p.__doc__) # 显示该函数的内置说明文档 对象名.__doc__ 或者 类名.__doc__
print(p.__module__) # __main__
把对象当做字典操作
class Person(object):
def __init__(self,name,age) -> None:
self.name = name
self.age = age
def run(self):
print(self.name + '正在吃饭')
def __setitem__(self,key,value): # 当前的示例, key='zhangsan'
self.__dict__[key] = value
def __getitem__(self,item):
return self.__dict__[item]
p = Person('张三',18)
# 将对象转换成一个字典
print(p.__dict__) # {'name': '张三', 'age': 18}
# 不能直接把一个对象当做字典来进行操作
# p['name'] = 'jack' # 'Person' object does not support item assignment
# 字典的 [] 语法,实际上会调用对象的 __setitem__ 方法
p['name'] = 'jack'
print(p.name) # jack
# 如果需要获取值,实际上是调用对象的 __getitem__ 方法
print(p['name'])
对象属性和类属性
如下代码介绍了:
1.对象属性
2.类属性
class Person(object):
type = '人类' # 该属性在类中,但不在任何函数中,我们称之为类属性
def __init__(self,name,age) -> None:
self.name = name
self.age = age
# 对象 p1和p2 是通过 Person 类创建出来的实例对象
# name和age 是对象属性,在 __init__ 方法中,以参数的形式进行定义
# 是每一个实例对象都单独保存的属性
# 每个实例对象的属性,相互不影响
p1 = Person('张三',18)
p2 = Person('李四',22)
# 只要创建了一个实例对象,这个对象就有自己的name和age属性
# 类属性可以通过类对象,或者是实例对象进行获取
print(Person.type) # 人类
print(p1.type) # 人类
print(p2.type) # 人类
# 类属性只能通过类对象进行修改,实例对象不能修改类属性
p1.type = 'human' # 此处操作为 在p1实例对象中,新增了type属性,值为human;并不是修改了Person类的type属性
print(Person.type) # 人类
print(p1.type) # human
print(p2.type) # human
Person.type = 'woman' # 此处操作 修改了类属性
print(Person.type) # woman
print(p2.type) # woman
print(p1.type) # human
私有属性和方法
如下代码介绍了:
1.私有属性
2.获取私有属性的方法
from datetime import datetime
class Person(object):
def __init__(self,name,age) -> None:
self.name = name
self.age = age
self.__money = 1000 # 以两个下划线开始的变量是私有变量
# 定义一个get方法,获取到__money变量
def get_money(self):
# 意义:可以记录调用该私有变量的相关时间和信息
print('{}查询了余额信息'.format(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)
# 私有变量
print(p.name,p.age) # 可以直接获取到
# print(p.__money) # 私有变量不可以直接获取到: 'Person' object has no attribute '__money'
# 私有函数
# p.__demo() # 'Person' object has no attribute '__demo' 私有函数不能在函数外调用
p.test() # 我是demo函数,name=张三
# 或者使用对象名._类名__私有函数名来调用
p._Person__demo() # 我是demo函数,name=张三
# 获取私有变量的方法:
# 1. 使用对象._类名__私有变量名获取
print(p._Person__money) # 1000
# 2. 定义get和set方法来获取
print(p.get_money()) # 1000
# 3. 使用property来获取
类方法和静态方法
如下代码介绍了:
1.普通方法
2.类方法
3.静态方法
class Person(object):
type = 'human'
def __init__(self,name,age) -> None:
self.name = name
self.age = age
# 该方法保存在类中,当类的实例对象进行调用时,会和实例对象进行绑定
def eat(self,food):
print(self.name + '正在吃' + food)
# 静态方法
# 如果一个方法中没有用到任何对象的任何属性,可以将这个方法定义成static(静态方法)
# 可以当做普通的函数使用,仅仅是依赖于某个类
@staticmethod
def demo():
print('demo方法被调用了')
# 类方法
# 如果这个函数值用到了类属性,我们就可以把它定义成一个类方法
@classmethod
def test(cls):
# 类方法会有一个参数 cls,也不需要手动的传参,会自动传参
# cls 指的是类对象 cls == Person ==> True
print('类方法test被调用了')
print(cls.type)
p = Person('张三',18)
# 实例对象在调用方法时,不需要传递self参数,会自动把实例对象传递给self
p.eat('饼干') # 张三正在吃饼干 直接使用实例对象调用方法
# 对象方法还可以使用 类名.方法名()
# 使用类对象调用方法,不会自动传递self参数,需要手动指定self
Person.eat(p,"西红柿牛肉面") # 张三正在吃西红柿牛肉面
# 静态方法,没有用到对象的任何属性
Person.demo() # demo方法被调用了
p.demo() # demo方法被调用了
# 类方法调用
# 使用类名.方法名()调用
Person.test() # 类方法test被调用了 human
# 使用实例对象.方法名()调用
p.test() # 类方法test被调用了 human
- 实例方法
- 会用到实例对象的属性,self指向调用这个方法的实例对象
- 有两种调用的方式:
- 实例对象.方法名 ==> 不需要手动给 self 传参,会自动将实例对象传递给self
- 类方法.方法名 ==> 需要手动给 self 进程传参
- 类方法
- 会有一个参数cls,这个cls指的是类对象
- 如果一个方法只用到了类属性,可以将这个方法定义为类方法
- 静态方法
- 如果一个方法,即用不到实例对象,也用不到类对象
- 可以把这个方法定义为静态方法
- 可以用来给一系列方法归类
单例设计模式
class Singleton(object):
__instance = None
__is_first = True
@classmethod
def __new__(cls,*args,**kwargs):
if cls.__instance == None:
# 申请内存,创建一个对象,并把对象的类型设置为cls
cls.__instance = object.__new__(cls) # 修改类属性
return cls.__instance
def __init__(self,a,b) -> None:
if self.__is_first:
self.a = a
self.b = b
self.__is_first = False
# 调用 __new__ 方法申请内存
# 如果不重写 __new__ 方法,会调用 object 的 __new__ 方法
# object 的 __new__ 方法会申请内存
# 如果重写了 __new__ 方法,需要自己手动申请内存
p1 = Singleton('haha','hehe')
p2 = Singleton('xixi','huhu')
# print(type(p1))
print(p1 is p2)
print(p1.a,p1.b) # xixi huhu p2实例和p1实例使用同一块内存空间,创建p2时,将p1的信息重写了
#可以采用修改 __init__ 方法,来实现只创建一次实例
# 使用一个变量保存是否第一次创建,在__init__中,判断该变量
# 第一次调用该变量后即修改变量的值,可以保证当前实例只创建一次