Python、オブジェクトの作成


132

私はpythonを習得しようとしていますが、今はクラスのこつとインスタンスでそれらを操作する方法を取得しようとしています。

私はこの練習問題を理解できないようです:

名前、年齢、および専攻が入力として指定されたものと同じである生徒オブジェクトを作成して返します

def make_student(name, age, major)

オブジェクトの意味がわかりません。これらの値を保持する関数内に配列を作成する必要があるという意味ですか?またはクラスを作成し、この関数をその中に入れて、インスタンスを割り当てますか?(この質問の前に、名前、年齢、専攻の学生クラスを設定するように求められました)

class Student:
    name = "Unknown name"
    age = 0
    major = "Unknown major"

データモデルのドキュメントを読んでください。具体的には、__init__メソッドはここに関連しています: docs.python.org/2/reference/datamodel.html#object.__init__
wim

1
なし(引用符なし)は、Pythonの一般的な未割り当てのデフォルト値です
monkut

回答:


173
class Student(object):
    name = ""
    age = 0
    major = ""

    # The class "constructor" - It's actually an initializer 
    def __init__(self, name, age, major):
        self.name = name
        self.age = age
        self.major = major

def make_student(name, age, major):
    student = Student(name, age, major)
    return student

Pythonの哲学の原則の1つは「1つ(できれば1つだけ)の明白な方法である必要があります」ですが、これには複数の方法があることに注意してください。次の2つのコードスニペットを使用して、Pythonの動的機能を利用することもできます。

class Student(object):
    name = ""
    age = 0
    major = ""

def make_student(name, age, major):
    student = Student()
    student.name = name
    student.age = age
    student.major = major
    # Note: I didn't need to create a variable in the class definition before doing this.
    student.gpa = float(4.0)
    return student

私は前者を好みますが、後者が役立つ場合があります。1つはMongoDBなどのドキュメントデータベースを操作する場合です。


17
なぜ初期化の前にそれらをクラス変数として初期化するのですか?(好奇心が強い。そのパターンをあまり頻繁に見たことがない)
GoingTharn 2013

7
読みやすさのため。initの前にクラス変数を先頭近くに配置することで、コンストラクターによってすべて設定されない可能性があるため、クラススコープ内にある変数をすばやく確認できます。
Wulfram 2013年

1
ここで、クラスStudentのインスタンスであるオブジェクトの名前は、Studentのままです。呼び出しごとに、student01、student02、...という名前の複数のオブジェクトが必要な場合はどうすればよいですか?
Yathi、2014年

9
クラス変数を作成してインスタンス変数を確認するのはひどい習慣です。初心者の読者へ:代わりに@pyrospadeの答えを見てください。
anon01

2
あなたの例は誤解を招くものです。各生徒のプロパティを誤用するのではなく、実際にはすべての生徒のプロパティであるクラス変数名を使用してください。たとえばclass Unicorn、のhas_hooves = True代わりにおよびを使用しますname = ""
Tim Kuipers、2018

49

クラスを作成して__init__メソッドを与える:

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

    def is_old(self):
        return self.age > 100

これで、Studentクラスのインスタンスを初期化できます。

>>> s = Student('John', 88, None)
>>> s.name
    'John'
>>> s.age
    88

make_studentと同じことをするのになぜ学生機能が必要なのかはわかりませんがStudent.__init__


私たちの先生は、問題が正しく行われたかどうかをテストするtest.pyプログラムをくれました。この質問では、特にmake_student関数を使用するよう求めています。最終目標は次のとおりです。s1= make_student(name、age、major)そして今、すべてをs1に割り当てています。しかし、もう一度、私は彼らがs1になりたいと思っていますか?配列{'name':name..etc}でこれを行うことができますが、それは正しい答えを与えなかったので、クラスとインスタンスから学んだことを実装する必要があると仮定しています
Mohsen M. Alrasheed

1
いわゆる「ファクトリーメソッド」パターンは、メソッドまたは関数を使用して、コード内で直接オブジェクトを作成するのではなく、何らかのオブジェクトを作成するパターンであり、たとえば、継承に関する優れた点を活用することができます。 。見上げてください;)
bracco23 2016年

28

オブジェクトはクラスのインスタンスです。クラスはオブジェクトの青写真にすぎません。クラス定義を考えると-

# Note the added (object) - this is the preferred way of creating new classes
class Student(object):
    name = "Unknown name"
    age = 0
    major = "Unknown major"

-のmake_student新しいインスタンスに属性を明示的に割り当てることにより、関数を作成できます。Student

def make_student(name, age, major):
    student = Student()
    student.name = name
    student.age = age
    student.major = major
    return student

しかし、おそらくこれをコンストラクタ(__init__)で行う方が理にかなっています-

class Student(object):
    def __init__(self, name="Unknown name", age=0, major="Unknown major"):
        self.name = name
        self.age = age
        self.major = major

を使用すると、コンストラクタが呼び出されますStudent()__init__メソッドで定義された引数を取ります。コンストラクタの署名は基本的にStudent(name, age, major)

あなたがそれを使うなら、make_student関数は取るに足らない(そして余分な)-

def make_student(name, age, major):
    return Student(name, age, major)

おもしろいのはmake_student、クラスを定義せずに関数を作成する方法の例です。自宅でこれを試さないでください。

def make_student(name, age, major):
    return type('Student', (object,),
                {'name': name, 'age': age, 'major': major})()

実際、私はクラスName(object)を実行しないことを好みます:冗長性の理由から。Pythonのドキュメントでも同様の傾向があります。私はディクテーションを食べさせる「危険な」例が好きです。 docs.python.org/2/tutorial/classes.html
Wulfram

1
以前のコメントを取り消します。stackoverflow.com/questions/4015417/…を参照してください。だから、クラス名(オブジェクト)を綴るする理由は、実際にそこにある:
Wulfram

1
Pythonにはコンストラクタはありません:)
BigSack '13年

どのように__init__()この方法では、コンストラクタは異なりますか?
ピロスペード、2014年

1
__init__はコンストラクタではありません。「オブジェクト__init__が呼び出されるまでにオブジェクトはすでに構築されており、クラスの新しいインスタンスへの有効な参照がすでにあるためです。」(diveintopython.net/object_oriented_framework/...
ブライアン・Z

3

predefineクラスを使用してオブジェクトを作成する場合、最初にそのオブジェクトを格納するための変数を作成します。次に、オブジェクトを作成し、作成した変数を格納できます。

class Student:
     def __init__(self):

# creating an object....

   student1=Student()

実際、このinitメソッドはクラスのコンストラクタです。いくつかの属性を使用してそのメソッドを初期化できます。その時点で、オブジェクトを作成するときに、特定の属性にいくつかの値を渡す必要があります。

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

 # creating an object.......

     student2=Student("smith",25)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.