Python の基礎-12 オブジェクト指向プログラミング_属性とメソッド

組み込みプロパティ

組み込み関数を使用すると、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 はこのメソッドを呼び出すインスタンス オブジェクトを指します。
    • 呼び出す方法は 2 つあります。
      • インスタンス オブジェクト。メソッド名 ==> パラメーターを手動で 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__中,判断该变量
# 第一次调用该变量后即修改变量的值,可以保证当前实例只创建一次

おすすめ

転載: blog.csdn.net/Lz__Heng/article/details/130212980